概述
创建 Laravel 项目后,错误与异常处理已预先配置好。 自定义配置可在bootstrap/app.php 的 withExceptions 方法中进行。
异常处理流程
下面展示了从异常发生到返回响应给客户端的流程。withExceptions 闭包的 $exceptions 对象是 Illuminate\Foundation\Configuration\Exceptions 的实例,用于管理整个应用的异常处理。
调试设置
config/app.php 的 debug 选项控制错误信息的显示量。
默认使用 .env 中 APP_DEBUG 环境变量的值。
异常的报告
异常的报告,是指将异常记录到日志或发送到 Laravel Nightwatch、Sentry、Flare 等外部服务的处理。 默认情况下会基于config/logging.php 的配置记录到日志。
自定义报告回调
若希望根据异常类型进行不同的报告处理,可向report 方法传入闭包。
Laravel 会根据闭包的类型提示判断异常类型。
stop() 或返回 false。
report() 辅助函数
如果只想报告异常而不显示错误页,可以使用 report() 辅助函数。
防止重复报告
同一个异常实例多次传入report() 时,可能会在日志中产生重复条目。
设置 dontReportDuplicates() 后,同一实例只会记录第一次。
全局日志上下文
若希望为所有异常日志附加公共信息,可以使用context 方法。
当前用户 ID 若可用会被自动附加。
为异常类添加 context() 方法
在异常类自身定义 context() 方法后,可以将该异常特有的上下文信息包含在日志中。
日志级别的更改
若希望以特定日志级别记录特定异常,可使用level 方法。
异常报告的限流
在大量异常发生时,可通过throttle 方法控制报告数量。
Limit。
异常的渲染
渲染是指将异常转换为 HTTP 响应的处理。 默认情况下 Laravel 会自动生成合适的响应,也可以自定义。自定义渲染回调
向render 方法传入闭包,将异常转换为响应。
NotFoundHttpException)的渲染。
若闭包不返回值,则使用默认渲染。
JSON / HTML 的自动判定
Laravel 会根据请求的Accept 头自动判定返回 HTML 还是 JSON。
若想自定义该判定逻辑,可使用 shouldRenderJsonWhen。
对整个响应的定制
使用respond 方法可以对生成的响应做进一步加工。
自定义异常类
可以在app/Exceptions/ 目录中创建自己的异常类。
若定义了 report() 和 render() 方法,即使不在 bootstrap/app.php 中配置也会被自动调用。
异常类的创建
1
创建异常类
2
实现 report() 与 render()
report() 方法可以通过类型提示使用依赖注入。Laravel 的服务容器会自动解析。ShouldntReport 接口
对于不需要报告的异常,可以实现 ShouldntReport 接口。
实现该接口的异常将不会被报告。
异常的抛出
abort() 辅助函数
可以在应用的任意位置产生 HTTP 错误响应。
abort_if() / abort_unless()
条件式抛出异常的辅助函数。
异常的全局控制
忽略特定异常
使用dontReport 指定不报告的异常。渲染的自定义逻辑仍然生效。
dontReportWhen 传入闭包。
Laravel 默认自动忽略 404 错误、CSRF 令牌无效(419)、来源不匹配(403)等部分异常。
恢复 Laravel 默认忽略的异常
要将默认忽略的异常恢复为报告对象,可使用stopIgnoring。
HTTP 错误页
Laravel 允许按 HTTP 状态码定义自定义错误视图。自定义错误视图的创建
在resources/views/errors/ 目录中创建以状态码为文件名的 Blade 模板。
$exception 变量访问错误信息。
发布默认错误模板
若希望以 Laravel 标准错误页作为自定义起点,可通过vendor:publish 获取。
回退错误页
对于没有对应视图的状态码,可以创建4xx.blade.php 和 5xx.blade.php 作为回退。
实践示例:API 异常处理器
对于提供 API 的应用,异常需要始终以 JSON 形式返回。 下面是在bootstrap/app.php 中统一管理 API 错误的实现示例。
自定义 API 异常类的实现
创建 API 专用的基础异常类,可在各端点返回统一的错误响应。小结
异常报告小结
异常报告小结
异常渲染小结
异常渲染小结
HTTP 错误页小结
HTTP 错误页小结
- 只需创建
resources/views/errors/404.blade.php等文件即可自动使用 - 可通过
$exception变量访问错误详情 - 可通过
php artisan vendor:publish --tag=laravel-errors获取默认模板 - 可通过
4xx.blade.php/5xx.blade.php定义回退页面
生产环境最佳实践
生产环境最佳实践
- 务必设置
APP_DEBUG=false,不向用户暴露堆栈跟踪 - 与 Sentry 或 Flare 等外部错误跟踪服务集成,统一管理错误
- 使用
throttle()防止大量异常时日志溢出 - 在 API 端点保持一致的 JSON 错误响应格式