【问题标题】:Disable throwing exceptions for E_USER_WARNING禁用 E_USER_WARNING 的抛出异常
【发布时间】:2017-11-23 19:27:41
【问题描述】:

当我这样做时,Laravel 会返回 500:

trigger_error("Some message", E_USER_WARNING);

我需要它出错,但我确实希望它通过\App\Exceptions\Handler::report 运行,它将警告记录到 Sentry。

如何使用 Laravel 5.2 禁用将警告和错误转换为异常?

【问题讨论】:

  • 它不会触发500错误,你确定你没有错过;行后?
  • @Exprator 我确定这不是语法错误,它肯定会抛出一个ErrorException 并通过\App\Exceptions\Handler::render,它会当场返回响应,而不是像我想要的那样继续。

标签: php laravel exception-handling laravel-5.2


【解决方案1】:

我认为应该由php来处理。你试过error_reporting()吗? set_error_handler

更多信息:

开箱即用,Laravel 支持将日志信息写入单个文件、每日文件、系统日志和错误日志。要配置 Laravel 使用的存储机制,您应该修改 config/app.php 配置文件中的 log 选项。例如,如果您希望使用每日日志文件而不是单个文件,则应将应用配置文件中的日志值设置为每天

laravel error and logging

【讨论】:

  • 设置error_reporting(E_ALL & ~E_USER_WARNING) 防止\App\Exceptions\Handler::report 被调用。如果我使用这种方法,我会将 Sentry 错误处理移到哪里?
  • 我不知道哨兵。但是您可以使用if ($exception instanseof ExceptionType) 捕获处理程序中的任何异常和/或检查其他详细信息。那么你可以在 if 语句的正文中发送哨兵日志。
  • 在哪里?如果条件,我会把它放在哪里?因为当它到达\App\Exceptions\Handler::report 时已经太晚了——我无法从那里恢复并继续正常的代码流。这是整个问题。
  • 是的!你不能从那里回去。您可以只向用户发送消息。只需将此逻辑添加到 render() 函数。
【解决方案2】:

由于在ErrorHandler内部无法显示页面的正常内容,所以只好再抛出一个错误信息:

Route::get('error', function() {
    $client = new Raven_Client(env("SENTRY_DSN"));
    $client->captureMessage("Some Warning", ['log'], [
        'level' => 'warning'
    ]);
});

这将为哨兵创建一个自定义警告条目,而不会在 php 中引发会停止正常代码的真正错误。

你也可以将它包装在一个函数中

function trigger_sentry_warning($message) {
    $client = new Raven_Client(env("SENTRY_DSN"));
    $client->captureMessage($message, ['log'], [
        'level' => 'warning'
   ]);
}

【讨论】:

  • 所以....基本上我不能使用trigger_error?这很糟糕,因为我在我的非 Laravel 应用程序中做了很多。如果 Laravel 没有从 set_error_handlerthrow an ErrorException 并且只是在里面正确处理它,一切都会好起来的。
  • 你可以覆盖 trigger_error 函数来实现缺失的逻辑
  • “覆盖” trigger_error 函数是什么意思?你的意思是那个APD PECL扩展?我认为这不是一个好方法。
  • 你可以检查错误处理程序,如果它是一个警告,但你可以回来继续代码。当 Laravel 在错误处理程序中时,它想要生成一个新视图,因此使用 sentry 进行日志记录必须在此类之外。覆盖我的意思是,您再次声明该函数并将支票放入其中,这样您就不必到处替换它
【解决方案3】:

您可以编辑 laravel 的错误处理程序以仅在 HandleExceptions.php 中报告警告

public function handleError($level, $message, $file = '', $line = 0, $context = [])
{
    $exception = new ErrorException($message, 0, $level, $file, $line);

    if (E_USER_WARNING & $level) {
        $this->getExceptionHandler()->report($exception);
    }
    elseif (error_reporting() & $level) {
        throw $exception;
    }
}

用户警告:修改供应商代码通常是个坏主意。

您可以通过扩展HandleExceptions 类并在Kernel.php 中注册您的新类来避免修改供应商代码

MyHandleExceptions extends HandleExceptions {
    public function handleError($level, $message, $file = '', $line = 0, $context = [])
    {   
        if (E_USER_WARNING & $level) {
            $this->getExceptionHandler()->report(new ErrorException($message, 0, $level, $file, $line));
        }
        else {
            return parent::handleError($level, $message, $file, $line, $context);
        }
    }
}

【讨论】:

  • 我是否必须覆盖整个 $bootstrappers 才能注册我的自定义错误处理程序?
  • @mpen 是的,将所有$bootstrappers 复制到app/Http/Kernel.php 并替换HandleExceptions
猜你喜欢
  • 2016-03-26
  • 2013-05-24
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
  • 2012-01-24
相关资源
最近更新 更多