Yii2: use error handler only for fatal errors or s

2019-06-21 22:30发布

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.

1条回答
小情绪 Triste *
2楼-- · 2019-06-21 22:56

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.

查看更多
登录 后发表回答