如何使用Laravel将自定义异常通过Sentry进行报告与处理?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1024个文字,预计阅读时间需要5分钟。
直接修改+App\Exceptions\Handler+是最高稳妥的接入方式,Laravel 9 默认已支持+report()+方法的异常委托机制,无需重写整个异常处理流程。
关键点是:不要覆盖 report() 原逻辑,而是用 Sentry\Laravel\EventHandler::report() 委托上报,同时保留 Laravel 原生日志(如本地开发时仍需看 storage/logs/laravel.log)。
- 确保已通过
composer require sentry/sentry-laravel安装,并运行过php artisan sentry:publish --force - 检查
.env中是否设置了SENTRY_LARAVEL_DSN=...,空值或注释掉会导致静默失败 - 在
app/Exceptions/Handler.php的report()方法中插入委托调用:if (app()->bound('sentry')) { \Sentry\Laravel\EventHandler::report($exception); }
- 别漏掉
use Sentry\Laravel\EventHandler;,否则会报Class 'EventHandler' not found
为什么不能只依赖 sentry/sentry-laravel 的自动注册
自动注册(即不改 Handler)仅在未自定义 report() 时生效;一旦你重写了该方法(比如加了自定义日志逻辑),Sentry 的默认监听就会被跳过——这是 Laravel 异常委托机制决定的,不是 Sentry 插件的 bug。
常见错误现象:try { throw new \Exception('test'); } catch (\Exception $e) { report($e); } 在本地不报错、也不进 Sentry,就是因为 report() 被覆盖后没手动转发。
- 自动注册本质是向 Laravel 的
ExceptionHandler注册了一个report闭包,优先级低于你写的类方法 - 如果你用了
Log::error()或logger()->error()手动记录异常,这些不会触发 Sentry 上报,必须走report($e) - 测试是否生效:临时在路由里写
throw new RuntimeException('sentry-test');,然后查 Sentry 控制台的「Recent Events」,别只看本地日志
app('sentry') 报 Target class [sentry] does not exist 怎么办
这个错误说明 Sentry 服务提供者没加载成功,通常发生在安装后没清缓存,或配置文件缺失。
- 执行
php artisan config:clear和php artisan cache:clear,Laravel 会重新扫描config/app.php中的providers - 确认
config/app.php的providers数组里有Sentry\Laravel\ServiceProvider::class(Laravel 5.5+ 一般自动发现,但升级或手动安装时可能遗漏) - 检查
config/sentry.php是否存在;如果不存在,说明php artisan sentry:publish没成功运行,或权限不足导致写入失败 - 若使用 Octane/Swoole,注意 Sentry 初始化时机:需在
bootstrap/app.php中提前调用\Sentry\init(),否则热重载下app('sentry')可能为 null
生产环境漏报异常?重点检查这三处
Sentry 不上报 ≠ 代码没跑,更可能是异常被吞掉、过滤掉、或网络卡住。比 DSN 写错更隐蔽的问题往往藏在这几个地方。
-
SENTRY_ENVIRONMENT配置为空或与 Sentry 项目设置不一致,会导致事件被丢弃(尤其当项目启用了 Environment Filter) -
config/sentry.php中的in_app_exclude列表误加了app/,结果所有业务异常都被标记为「第三方代码」而折叠 - Laravel 的
ignore_exceptions配置(在app/Exceptions/Handler.php的$dontReport属性)会阻止上报,比如ValidationException默认就在其中——如需上报,得手动从数组里删掉它
复杂点在于:Sentry SDK 默认不抛出自身错误,即使 DSN 格式错误、网络超时,你也看不到提示。建议上线前用 php artisan tinker 手动调用 \Sentry\captureException(new \Exception('test')) 验证端到端连通性。
本文共计1024个文字,预计阅读时间需要5分钟。
直接修改+App\Exceptions\Handler+是最高稳妥的接入方式,Laravel 9 默认已支持+report()+方法的异常委托机制,无需重写整个异常处理流程。
关键点是:不要覆盖 report() 原逻辑,而是用 Sentry\Laravel\EventHandler::report() 委托上报,同时保留 Laravel 原生日志(如本地开发时仍需看 storage/logs/laravel.log)。
- 确保已通过
composer require sentry/sentry-laravel安装,并运行过php artisan sentry:publish --force - 检查
.env中是否设置了SENTRY_LARAVEL_DSN=...,空值或注释掉会导致静默失败 - 在
app/Exceptions/Handler.php的report()方法中插入委托调用:if (app()->bound('sentry')) { \Sentry\Laravel\EventHandler::report($exception); }
- 别漏掉
use Sentry\Laravel\EventHandler;,否则会报Class 'EventHandler' not found
为什么不能只依赖 sentry/sentry-laravel 的自动注册
自动注册(即不改 Handler)仅在未自定义 report() 时生效;一旦你重写了该方法(比如加了自定义日志逻辑),Sentry 的默认监听就会被跳过——这是 Laravel 异常委托机制决定的,不是 Sentry 插件的 bug。
常见错误现象:try { throw new \Exception('test'); } catch (\Exception $e) { report($e); } 在本地不报错、也不进 Sentry,就是因为 report() 被覆盖后没手动转发。
- 自动注册本质是向 Laravel 的
ExceptionHandler注册了一个report闭包,优先级低于你写的类方法 - 如果你用了
Log::error()或logger()->error()手动记录异常,这些不会触发 Sentry 上报,必须走report($e) - 测试是否生效:临时在路由里写
throw new RuntimeException('sentry-test');,然后查 Sentry 控制台的「Recent Events」,别只看本地日志
app('sentry') 报 Target class [sentry] does not exist 怎么办
这个错误说明 Sentry 服务提供者没加载成功,通常发生在安装后没清缓存,或配置文件缺失。
- 执行
php artisan config:clear和php artisan cache:clear,Laravel 会重新扫描config/app.php中的providers - 确认
config/app.php的providers数组里有Sentry\Laravel\ServiceProvider::class(Laravel 5.5+ 一般自动发现,但升级或手动安装时可能遗漏) - 检查
config/sentry.php是否存在;如果不存在,说明php artisan sentry:publish没成功运行,或权限不足导致写入失败 - 若使用 Octane/Swoole,注意 Sentry 初始化时机:需在
bootstrap/app.php中提前调用\Sentry\init(),否则热重载下app('sentry')可能为 null
生产环境漏报异常?重点检查这三处
Sentry 不上报 ≠ 代码没跑,更可能是异常被吞掉、过滤掉、或网络卡住。比 DSN 写错更隐蔽的问题往往藏在这几个地方。
-
SENTRY_ENVIRONMENT配置为空或与 Sentry 项目设置不一致,会导致事件被丢弃(尤其当项目启用了 Environment Filter) -
config/sentry.php中的in_app_exclude列表误加了app/,结果所有业务异常都被标记为「第三方代码」而折叠 - Laravel 的
ignore_exceptions配置(在app/Exceptions/Handler.php的$dontReport属性)会阻止上报,比如ValidationException默认就在其中——如需上报,得手动从数组里删掉它
复杂点在于:Sentry SDK 默认不抛出自身错误,即使 DSN 格式错误、网络超时,你也看不到提示。建议上线前用 php artisan tinker 手动调用 \Sentry\captureException(new \Exception('test')) 验证端到端连通性。

