首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Laravel 6中用堆栈跟踪向ModelNotFoundException报告Sentry.io?

如何在Laravel 6中用堆栈跟踪向ModelNotFoundException报告Sentry.io?
EN

Stack Overflow用户
提问于 2022-02-18 11:51:39
回答 2查看 247关注 0票数 0

我使用了下面的laravel 6代码来报告Sentry.io的异常:

代码语言:javascript
复制
public function report(Exception $exception)
{
    if ($this->shouldReport($exception) && app()->bound('sentry')) {
        app('sentry')->captureException($exception);
    }

    parent::report($exception);
}

所有例外情况都可以向哨兵报告。然而,最近我发现ModelNotFoundException并没有发送到Sentry。另外,我找到了原因,这是因为文件(Illuminate\Foundation\Exceptions\Handler.php):的下面代码中存在ModelNotFoundException。

代码语言:javascript
复制
protected $internalDontReport = [
        AuthenticationException::class,
        AuthorizationException::class,
        HttpException::class,
        HttpResponseException::class,
        ModelNotFoundException::class,
        SuspiciousOperationException::class,
        TokenMismatchException::class,
        ValidationException::class,
    ];

作为内置代码,我不能在上面的代码中删除ModelNotFoundException。有没有办法让ModelNotFoundException去哨兵?

EN

回答 2

Stack Overflow用户

发布于 2022-04-15 19:09:17

$internalDontReport是受保护的,所以您可以重写它,不过最好不要太过,因为列表将来可能会改变,并且需要您保持它的同步。

您可以删除$this->shouldReport($exception),但是这将导致报告所有那些忽略的异常,而这些异常可能不是您想要的。

如果你只关心ModelNotFoundException,你可以这样做

代码语言:javascript
复制
    protected $doReportToSentry = [
        \Illuminate\Database\Eloquent\ModelNotFoundException::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(\Illuminate\Support\Arr::first($this->doReportToSentry, function ($type) use ($e) {
            return $e instanceof $type;
        }));
    }

您可以向该$doReportToSentry数组添加任何您希望确保它被报告的类,即使Laravel (默认情况下)可能忽略它。

票数 0
EN

Stack Overflow用户

发布于 2022-10-09 22:59:26

我自己也遇到了类似的问题,当找不到应该始终存在的模型时,findOrFail返回404响应。我希望它返回一个500并将它记录下来,这样我就可以知道数据库的不一致性。

我的解决方案是在App\Exceptions\Handler.php中覆盖几个方法,如下所示:

代码语言:javascript
复制
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并使其看起来像是根实体丢失的问题。

例如,如果您希望所有用户都与一个角色模型有关系,而有一个用户没有角色,那么我的更改使Laravel不会返回404错误。这是一个数据库不一致,应该是一个500错误。404错误会使它看起来像是找不到用户,这是假的。找不到的是角色,而不是用户。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71173032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档