samdark / yii2-cookbook

Yii 2.0 Community Cookbook

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to override error handler from a module

samdark opened this issue · comments

class Module extends \yii\base\Module
{
    public function init()
    {
        parent::init();
        \Yii::configure($this, [
            'components' => [
                'errorHandler' => [
                    'class' => ErrorHandler::className(),
                ]
            ],
        ]);

        /** @var ErrorHandler $handler */
        $handler = $this->get('errorHandler');
        \Yii::$app->set('errorHandler', $handler);
        $handler->register();
    }
}

I encountered with this Error:

Not instantiable – yii\di\NotInstantiableException

Can not instantiate yii\base\ErrorHandler.

What's the issue?

The issue is that you're trying to use Yii's base error handler which is, in fact, non instantiable.

Oh, yes i have to using yii\web\ErrorHandler instead yii\base\ErrorHandler
(The use yii\base\ErrorHandler was inserted with PhpStorm automatically ;) )

In my opinion is better set module error handler in beforeAction method, so that application error handler does not overwrite.

class Module extends \yii\base\Module
{
    public function beforeAction($action)
    {
        parent::init();
        \Yii::configure($this, [
            'components' => [
                'errorHandler' => [
                    'class' => ErrorHandler::className(),
                    'errorAction' => '/module/default/error',
                ]
            ],
        ]);

        /** @var ErrorHandler $handler */
        $handler = $this->get('errorHandler');
        \Yii::$app->set('errorHandler', $handler);
        $handler->register();

         return parent::beforeAction($action);
    }
}

I now confused how can handle www.site.com/module/x with module error handler(www.site.com/module/default/error)? (where x is not a valid controller). It now handle with site error handler(www.site.com/site/error).


Finally i used this code:

class AdminModule extends \yii\base\Module
{
    public function init()
    {
         parent::init();

        // Is better used regex method, temporally i used this method
        $r = Yii::$app->urlManager->parseRequest(Yii::$app->request)[0];
        $r_array = explode('/',$r);

        if($r_array[0] === 'admin'){
            Yii::configure($this, [
                'components' => [
                    'errorHandler' => [
                        'class' => ErrorHandler::className(),
                        'errorAction' => '/admin/default/error',
                    ]
                ],
            ]);

            $handler = $this->get('errorHandler');
            Yii::$app->set('errorHandler', $handler);
            $handler->register();
        }

    }
}

Hi samdark. Can you please clarify a bit your first post? Is it a guide? Iis a bug report for Yii FW?
I work on a Yii2 extension and I wanted to change the error action. Based on the Yii guide I used the code

Yii::configure($this, require __DIR__ . '/config/web.php');

So exactly the first part of your post, but conf is placed in a separate file.
But I was surprised that it didn’t work.

Then I found your post, added the last three lines and it worked. Great.
But I’d rather understand the solution, not just copy paste it.

So why do I have to use the three lines? Why the error handler isn’t changed in init()?
I even tried to put the config part into bootstrap class where I have some url rules (and they work), but it didn’t changed anything.

Thank you.

It is a proposal for Yii 2 cookbook recipe.

There's no such thing as module's error handler so we have to overwrite application one. Last three lines replacing current error handler with new error handler.

Hi, does this proposal works in latest versions?
When application starts it register default error handler by register_shutdown_function([$this, 'handleFatalError']);
from yii\base\ErrorHandler -> register()
And public function handleException($exception) contains exit(1);
So registered custom handler will not start because script finished

Hi, does this proposal works in latest versions? When application starts it register default error handler by register_shutdown_function([$this, 'handleFatalError']); from yii\base\ErrorHandler -> register() And public function handleException($exception) contains exit(1); So registered custom handler will not start because script finished

I recently tested it on Yii version 2.0.48.1. - everything is fine, there are no errors.