Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yii2: use error handler only for fatal errors or specify handled error types

Yii2 has it's own error handler, that converts all non-fatal php errors into catchable exceptions.

Is it possible to use it only for handling fatal errors or (better) explicitly specify, which errors should be handled by yii error handler, and which should be processed by internal php handler?

I.e. in dev environment I want all errors to throw an exceptions and provide error page with trace.

But in prod environment I want only fatal errors to render error page with yii, but notices and warnings should just go to standard php log without throwing an exeption.

Currently if I set YII_ENABLE_ERROR_HANDLER to true, I get exception on notices (I do not want it on prod); if I set it to false, I loose yii fatal error pages; and it I set it to true and set error_reporting to 0, I loose error logging.

like image 401
cronfy Avatar asked Feb 20 '16 11:02

cronfy


People also ask

How to display error in yii?

If you want to show an error page telling the user that his request is invalid or unexpected, you may simply throw an HTTP exception, such as yii\web\NotFoundHttpException. The error handler will correctly set the HTTP status code of the response and use an appropriate error view to display the error message.

How do I enable error reporting in yii?

1 Disable Or EnableThe Yii2 error handler is enabled by default. You can disable it by adding following code to your application entry script: YOUR_APP_FOLDER/web/index.

How do I show PHP errors?

Quickly Show All PHP Errors The quickest way to display all php errors and warnings is to add these lines to your PHP code file: ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL);

Where are yii logs?

yii\log\DbTarget: stores log messages in a database table. yii\log\EmailTarget: sends log messages to pre-specified email addresses. yii\log\FileTarget: saves log messages in files. yii\log\SyslogTarget: saves log messages to syslog by calling the PHP function syslog() .

How does the Yii error handler work?

Yii includes a built-in error handler which makes error handling a much more pleasant experience than before. In particular, the Yii error handler does the following to improve error handling: All non-fatal PHP errors (e.g. warnings, notices) are converted into catchable exceptions.

What is a catchable exception in Yii?

In Yii, non-fatal PHP errors (e.g. warnings and notices) are routed into catchable exceptions so you can decide how to react and respond to them. You can designate a controller action to process all of these exceptions. And you can customize the display format for errors, e.g. HTML, JSON, XML, etc.

Can I customize the display format for errors in Yii?

And you can customize the display format for errors, e.g. HTML, JSON, XML, etc. Exceptions and fatal PHP errors can be assessed only in debug mode. In these kinds of development scenarios, Yii can display detailed call stack information and segments of source code (you can see this above in the title image).

How do I throw an HTTP error in Yii?

If you want to show an error page telling the user that his request is invalid or unexpected, you may simply throw an HTTP exception, such as yii\web\NotFoundHttpException. The error handler will correctly set the HTTP status code of the response and use an appropriate error view to display the error message.


1 Answers

EDIT: I created a package that implements behavior described below.

Yii2's error handler cannot be configured in this way. But it is possible to create own error handler, extending yii\web\ErrorHandler (or yii\console\ErrorHandler if required).

namespace app\web;

use yii\web\ErrorHandler as BaseErrorHandler;

class ErrorHandler extends BaseErrorHandler {


    /**
     * @var array Used to specify which errors this handler should process.
     *
     * Default is ['fatal' => true, 'catchable' => E_ALL | E_STRICT ]
     *
     * E_ALL | E_STRICT is a default from set_error_handler() documentation.
     *
     * Set
     *     'catchable' => false
     * to disable catchable error handling with this ErrorHandler.
     *
     * You can also explicitly specify, which error types to process, i. e.:
     *     'catchable' => E_ALL & ~E_NOTICE & ~E_STRICT
     */
    public $error_types;

    /**
     * @var boolean Used to specify display_errors php ini setting
     */
    public $display_errors = false;

    /**
     * @var string Used to reserve memory for fatal error handler.
     */
    private $_memoryReserve;
    /**
     * @var \Exception from HHVM error that stores backtrace
     */
    private $_hhvmException;

    /**
     * Register this error handler
     */
    public function register()
    {
        // by default process all errors
        // E_ALL | E_STRICT is a default from set_error_handler() documentation
        $default_error_types = [ 'fatal' => true, 'catchable' => E_ALL | E_STRICT ];
        // merge with application configuration
        $error_types = array_merge($default_error_types, (array) $this->error_types);

        ini_set('display_errors', $this->display_errors);
        set_exception_handler([$this, 'handleException']);
        if (defined('HHVM_VERSION')) {
            set_error_handler([$this, 'handleHhvmError'], $error_types['catchable']);
        } else {
            set_error_handler([$this, 'handleError'], $error_types['catchable']);
        }
        if ($this->memoryReserveSize > 0) {
            $this->_memoryReserve = str_repeat('x', $this->memoryReserveSize);
        }
        if ($error_types['fatal']) {
            register_shutdown_function([$this, 'handleFatalError']);
        }
    }

}

Then it is possible to configure the error handler:

'components' => [
    'errorHandler' => [
        'class' => 'app\web\ErrorHandler',
        'error_types' => [
            'fatal' => true,
            'catchable' => YII_DEBUG ? (E_ALL | E_STRICT) : false
        ],
        'display_errors' => ini_get('display_errors')
    ],
],

In this example configuration we say that error handler should always handle fatal errors, but handle catchable errors only if we are in debug mode. In production mode all catchable errors will be handled by internal php error handler and will appear in error log if you configure it.

display_errors is said to inherit server php configuration from php.ini or .htaccess.

like image 97
cronfy Avatar answered Sep 30 '22 14:09

cronfy