我使用下面的laravel 6代码向Sentry.io:报告异常
public function report(Exception $exception)
{
if ($this->shouldReport($exception) && app()->bound('sentry')) {
app('sentry')->captureException($exception);
}
parent::report($exception);
}
所有异常都可以向哨兵报告。然而,最近我发现ModelNotFoundException没有发送到Sentry。此外,我发现了原因,这是由于文件的以下代码中存在ModelNotFoundException(Illuminate\Foundation\Exceptions\Handler.php(:
protected $internalDontReport = [
AuthenticationException::class,
AuthorizationException::class,
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
SuspiciousOperationException::class,
TokenMismatchException::class,
ValidationException::class,
];
作为内置代码,我无法删除上面代码中的ModelNotFoundException。有没有办法将ModelNotFoundException发送到sentry?
$internalDontReport
受到保护,因此您可以覆盖它,尽管最好不要覆盖它,因为列表将来可能会更改,并要求您保持同步。
您可以删除$this->shouldReport($exception)
,但这将导致所有被忽略的异常被报告,这可能不是您想要的。
如果你只关心ModelNotFoundException
:,你可以这样做
protected $doReportToSentry = [
IlluminateDatabaseEloquentModelNotFoundException::class,
];
public function report(Exception $e)
{
if ($this->shouldReportToSentry($e) && app()->bound('sentry')) {
app('sentry')->captureException($e);
}
parent::report($e);
}
protected function shouldReportToSentry(Exception $e)
{
if ($this->shouldReport($e)) {
return true;
}
return !is_null(IlluminateSupportArr::first($this->doReportToSentry, function ($type) use ($e) {
return $e instanceof $type;
}));
}
您可以向$doReportToSentry
数组添加任何要确保报告的类,即使Laravel可能(默认情况下(会忽略它
我自己也遇到过类似的问题,findOrFail
在找不到本应始终存在的模型时返回404响应。我希望它返回500并记录它,这样我就可以意识到数据库的不一致性。
我的解决方案是覆盖AppExceptionsHandler.php
中的几个方法,如下所示:
protected function shouldntReport(Throwable $e): bool
{
$shouldntReport = parent::shouldntReport($e);
return $e instanceof ModelNotFoundException ? false : $shouldntReport;
}
protected function prepareException(Throwable $e): Throwable
{
if ($e instanceof ModelNotFoundException) {
return $e;
}
return parent::prepareException($e);
}
第一个覆盖shouldntReport
会将错误写入日志。
第二个超控prepareException
导致返回500错误而不是404错误。
如果你对404错误很满意,只想将其记录下来(并发送到Sentry(,请随意只覆盖第一个方法。
请记住,如果你这样做,你需要检查模型是否存在,并在需要时手动返回404。但这将避免,例如,丢失的子实体返回404,并使其看起来像根实体丢失的问题。
例如,如果你希望所有用户都与一个角色模型有关系,而一个用户没有角色,我的更改使其不会返回404错误。这是数据库不一致,应该是500错误。404错误会使其看起来像是没有找到用户,这是错误的。找不到的是角色,而不是用户。
我是新手,无法对@Chris的回答发表评论。
我用的是Laravel 10。
由于类ModelNotFoundException扩展了RecordsNotFoundException,我不得不对进行此更改
protected function prepareException(Throwable $e): Throwable
{
if ($e instanceof ModelNotFoundException) {
return $e;
}
if ($e instanceof RecordsNotFoundException) {
return $e;
}
return parent::prepareException($e);
}