要让hyperf异常处理器输出可读、结构化、带上下文的错误,需确保异常路由准确(server name与exceptions.php中handler键名严格一致)、validation错误完整返回errors字段、http状态码与业务码分离设置、及时调用stoppropagation()终止传递,并精准匹配isvalid()条件。

要让Hyperf异常处理器真正输出可读、结构化、带上下文的错误,关键不是改响应体格式,而是确保异常能走到正确的处理器、不被跳过、不被静默吞掉,并把必要信息写进日志和响应。
确认 server name 与 handler 键名严格匹配
Hyperf按 HTTP Server 的 name 字段路由异常处理逻辑。若 server.php 中 HTTP server 的 name 是 api,exceptions.php 里就必须写 'api' => [...],不能是 'http' 或 'API'。
- 运行
php bin/hyperf.php start,看启动日志中类似[INFO] Server started: http://0.0.0.0:9501后面标注的 name 值 - 打开
config/autoload/server.php,找到'name' => 'xxx'配置项 - 打开
config/autoload/exceptions.php,确保 handler 数组的键与上一步完全一致(大小写敏感)
Validation 失败必须返回 errors 字段
默认 ValidationExceptionHandler 会返回 message 和 errors,但若自定义处理器里只调用 first(),就会丢掉全部字段错误。
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
- 在自定义
ValidationExceptionHandler的handle()方法中,用$throwable->validator->errors()->messages()获取关联数组 - 不要只取
first()或直接转 JSON 字符串,应构造标准结构:['message' => ..., 'errors' => [...]] - 确保
zh_CN/validation.php等语言文件存在且键名正确,否则 errors 内容为空
HTTP 状态码与业务码必须分离
异常类构造函数传入的 code 默认只是业务码,不会自动映射为 HTTP status。手动设置才能生效,但别乱用。
-
$throwable->getCode()应作为 JSON body 中的code字段,比如{"code": 1001, "message": "..."} - HTTP status 要显式调用
$response->withStatus(422)或withStatus(500),4xx/5xx 按语义选 - 避免把业务码(如 504)直接当 HTTP status 返回,会造成前端误判
务必调用 stopPropagation() 终止传递
不调用 $this->stopPropagation(),异常会继续交给下一个 handler。常见后果是日志重复、状态码被覆盖、自定义逻辑失效。
- 只要当前 handler 明确处理了该异常类型,就应在
handle()开头或结尾调用stopPropagation() - 如果只是记录日志但不接管响应,就不要调用,让后续 handler 继续处理
- 检查
isValid()是否精准匹配异常类型,避免宽泛判断导致不该拦截的异常也被捕获










