TP6接口异常处理核心是统一返回标准JSON格式,需识别请求类型(expectsJson或路由前缀)、控制响应格式(response()->json)、脱敏敏感信息,并按应用名分流处理。

TP6 接口异常处理的核心,是让所有 API 请求在出错时统一返回标准 JSON 格式,而不是 HTML 错误页或裸露的堆栈信息。关键不在“捕获异常”,而在“识别请求类型 + 控制响应格式 + 脱敏敏感内容”。
识别接口请求并强制 JSON 响应
默认 render() 会根据 Accept 头或 URL 后缀决定返回 HTML 还是 JSON,但 Postman、curl 或现代 fetch 往往不带 Accept: application/json,导致接口异常仍返回网页。必须主动判断:
- 用 $request->expectsJson() 判断客户端是否期望 JSON(比 isAjax() 更可靠,它不依赖 X-Requested-With 头)
- 结合路由前缀判断,例如检查 $request->path() 是否以 'api/' 开头,或使用 $request->routeIs('api.*')
- 满足任一条件,就调用 response()->json($data, $code) 返回,不要直接 return json(),否则会绕过状态码和中间件
自定义业务异常类并统一接管
把业务错误(如参数校验失败、权限不足、资源不存在)封装成继承 \Exception 或 \think\Exception 的类,例如 AppException:
- 在 app/exception/Handler.php 的 $dontReport 数组中加入该类,避免被当成系统错误写入日志
- 重写 shouldReport() 方法:当 $exception instanceof AppException 时返回 false
- 在 render() 中单独分支处理:if ($e instanceof AppException) { return response()->json([...], $e->getStatusCode()); }
生产环境敏感信息脱敏
app_debug = false 只控制是否显示调试页面,不自动过滤异常详情。需手动干预:
- 确认 config/app.php 中 'show_error_msg' => false 已生效(TP6.1+ 支持)
- 在 render() 中对非调试环境做字段裁剪:不返回 $e->getFile()、$e->getLine() 和 $e->getTraceAsString()
- 只保留用户可读的 message 和预设 error_code,必要时添加 trace_id 方便后台日志关联
多应用或多模块下的差异化处理
若项目含 manage、home、api 等多个应用,可按应用名分流异常响应逻辑:
- 在 app/Request.php 中扩展 app_name() 方法获取当前应用标识
- 在 Handler::render() 中用 switch 区分:manage 应用走默认 HTML 页面,api 应用始终返回 JSON
- 避免为不同应用重复写中间件或控制器注解,统一在异常处理器里做路由级判断

















