samdark / yii2-cookbook

Yii 2.0 Community Cookbook
1.45k stars 296 forks source link

How to override error handler from a module #168

Closed samdark closed 5 years ago

samdark commented 7 years ago
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();
    }
}
Saraylu commented 6 years ago

I encountered with this Error:

Not instantiable – yii\di\NotInstantiableException

Can not instantiate yii\base\ErrorHandler.

What's the issue?

samdark commented 6 years ago

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

Saraylu commented 6 years ago

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

Saraylu commented 6 years ago

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();
        }

    }
}
OndrejVasicek commented 5 years ago

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.

samdark commented 5 years ago

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.

pkvak-tdna commented 5 years ago

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

PC-Principal commented 3 months ago

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.