APP_DEBUG=false 是启用自定义错误页和生产级异常处理的前提;需同时设 APP_ENV=production,否则 resources/views/errors/ 下的 404.blade.php 等不会渲染,Handler::render() 也不接管异常。

APP_DEBUG 必须设为 false 才能启用自定义错误页和生产级异常行为;否则所有配置都无效。
APP_DEBUG=false 是一切生效的前提
本地开发时 APP_DEBUG=true 没问题,但只要部署到服务器,第一步就得确认 .env 里这行:APP_DEBUG=false
同时确保 APP_ENV=production。这两项不满足,resources/views/errors/404.blade.php 不会渲染,Handler::render() 也不会接管 HTTP 异常响应——你看到的仍是调试堆栈。
自定义错误页面只需放对文件名
不需要改 PHP 代码,Laravel 会自动匹配 resources/views/errors/ 下的视图文件:
-
404.blade.php→ 所有abort(404)或路由未匹配 -
500.blade.php→ 未捕获的 PHP 异常(如数据库连接失败) -
403.blade.php→ 权限拒绝(abort(403))
注意:$exception 变量在视图中可用,比如 {{ $exception->getMessage() }},但仅限 APP_DEBUG=false 时安全使用(不会暴露敏感路径或 SQL)。
Handler.php 的 render() 要按需接管异常类型
真正需要写逻辑的地方是 app/Exceptions/Handler.php 中的 render() 方法。常见做法:
- 用
instanceof区分业务异常:if ($exception instanceof InsufficientBalanceException)→ 返回 JSON 或跳转提示页 - 对
ModelNotFoundException统一转成 404:return response()->view('errors.404', [], 404); - 兜底返回 500 页面:
return response()->view('errors.500', [], 500);(放在render()最后)
别直接覆盖整个 parent::render(),否则会丢失 Laravel 对 ValidationException 等内置异常的友好处理(比如表单验证失败自动重定向并带错误消息)。
report() 里要过滤噪音日志
report() 决定哪些异常该记、哪些该忽略。默认会记录所有异常,但有些完全没必要:
- 把高频无害的异常加进
$dontReport数组:ModelNotFoundException::class、NotFoundHttpException::class - 避免日志刷屏,尤其是
404—— 它通常来自爬虫或输错 URL,不是程序缺陷 - 若要用 Sentry 或 Bugsnag,就在
report()里加对接逻辑,但记得先parent::report($exception)保证基础记录不丢
真正容易被忽略的是:日志级别设置(log_level=error)和保留天数(log_max_files=30)必须在 config/app.php 或 .env 显式配好,否则 daily 日志可能只留 5 天,排查时发现关键日志已被删。


















