如何高效处理Laravel框架中的错误和异常?

2026-04-27 20:261阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计651个文字,预计阅读时间需要3分钟。

如何高效处理Laravel框架中的错误和异常?

直接改写如下:

怎么在 render() 里区分网页请求和 API 请求

Laravel 默认对两者返回不同响应,但你得主动判断,不能只靠 $request->isJson() —— 它不可靠,很多前端发 JSON 时没带 Content-Type: application/json

  • $request->expectsJson() 才是正确姿势,它同时检查 Accept 头、X-Requested-With 和请求路径是否含 /api/
  • 网页请求走 Blade 错误页(如 resources/views/errors/404.blade.php),API 请求必须返回标准 JSON 结构 + 正确 HTTP 状态码
  • 别在 render() 里调用 dd() 或抛新异常,否则可能触发递归崩溃
  • ModelNotFoundException,网页返回 404 视图,API 返回 response()->json(['message' => 'Not found'], 404)

QueryException 的错误信息为什么总显示 “Integrity constraint violation”

因为 Laravel 把原始数据库错误包在了 $exception->getPrevious() 里,直接打 $exception->getMessage() 只能看到通用提示,查不到具体字段和值。

  • report() 中加判断:if ($exception instanceof QueryException && $previous = $exception->getPrevious()) { \Log::error('DB error detail', ['raw' => $previous->getMessage()]); }
  • MySQL 错误码 1062(重复键)、1452(外键约束)属于业务可预期错误,不该当 500 上报,应提前捕获并转为 400 或自定义异常
  • 线上环境禁止开启 DB::enableQueryLog(),它会吃内存且泄露 SQL 参数

自定义异常类该不该写进 $dontReport

该,但只针对真正“不值得记日志”的异常,比如表单验证失败、权限拒绝、资源未找到——它们高频、可预期、有明确语义。

  • Handlerregister() 方法里添加:$this->dontReport([ValidationException::class, AuthorizationException::class, ModelNotFoundException::class]);
  • 自己写的 InsufficientBalanceException 这类业务异常,如果需要监控,就别放 $dontReport;如果只是流程跳转用,可以加
  • $dontReport 不影响 render() 行为,只跳过 report() 调用,所以仍需在 render() 中处理它的展示逻辑

最容易被忽略的是:生产环境 APP_DEBUG=false 时,$exception 变量在 500 视图里依然可用,但 $exception->getTraceAsString() 会被静默截断——别指望靠它现场 debug,得靠 report() 里记录的完整上下文。

标签:Laravel

本文共计651个文字,预计阅读时间需要3分钟。

如何高效处理Laravel框架中的错误和异常?

直接改写如下:

怎么在 render() 里区分网页请求和 API 请求

Laravel 默认对两者返回不同响应,但你得主动判断,不能只靠 $request->isJson() —— 它不可靠,很多前端发 JSON 时没带 Content-Type: application/json

  • $request->expectsJson() 才是正确姿势,它同时检查 Accept 头、X-Requested-With 和请求路径是否含 /api/
  • 网页请求走 Blade 错误页(如 resources/views/errors/404.blade.php),API 请求必须返回标准 JSON 结构 + 正确 HTTP 状态码
  • 别在 render() 里调用 dd() 或抛新异常,否则可能触发递归崩溃
  • ModelNotFoundException,网页返回 404 视图,API 返回 response()->json(['message' => 'Not found'], 404)

QueryException 的错误信息为什么总显示 “Integrity constraint violation”

因为 Laravel 把原始数据库错误包在了 $exception->getPrevious() 里,直接打 $exception->getMessage() 只能看到通用提示,查不到具体字段和值。

  • report() 中加判断:if ($exception instanceof QueryException && $previous = $exception->getPrevious()) { \Log::error('DB error detail', ['raw' => $previous->getMessage()]); }
  • MySQL 错误码 1062(重复键)、1452(外键约束)属于业务可预期错误,不该当 500 上报,应提前捕获并转为 400 或自定义异常
  • 线上环境禁止开启 DB::enableQueryLog(),它会吃内存且泄露 SQL 参数

自定义异常类该不该写进 $dontReport

该,但只针对真正“不值得记日志”的异常,比如表单验证失败、权限拒绝、资源未找到——它们高频、可预期、有明确语义。

  • Handlerregister() 方法里添加:$this->dontReport([ValidationException::class, AuthorizationException::class, ModelNotFoundException::class]);
  • 自己写的 InsufficientBalanceException 这类业务异常,如果需要监控,就别放 $dontReport;如果只是流程跳转用,可以加
  • $dontReport 不影响 render() 行为,只跳过 report() 调用,所以仍需在 render() 中处理它的展示逻辑

最容易被忽略的是:生产环境 APP_DEBUG=false 时,$exception 变量在 500 视图里依然可用,但 $exception->getTraceAsString() 会被静默截断——别指望靠它现场 debug,得靠 report() 里记录的完整上下文。

标签:Laravel