hyperf协程错误调试需确保错误堆栈不丢失、日志匹配请求、上下文不串。一要校验exceptions.php中服务名与server.php一致且大小写敏感;二要启用lineformatter的include_stacktraces;三要手动注入correlation_id并日志中显式输出协程id和请求id。

Hyperf 开发环境里想看清协程运行时的错误,关键不是“打开调试开关”,而是让错误堆栈不丢、日志能对得上请求、上下文不串。协程一多,错误就容易淹没或错位,下面三点直击痛点。
确保验证失败返回完整 errors 字段
表单验证失败却只返回空 {"errors":{}} 或干脆 500?大概率是异常处理器没对上服务名。
- 运行
php bin/hyperf.php start,看启动日志里[INFO] Server started: http://0.0.0.0:9501对应的 name 值(比如api) - 打开
config/autoload/server.php,确认 HTTP server 的'name' => 'api'和上一步一致 - 打开
config/autoload/exceptions.php,检查'handler'数组中键名是否完全匹配,大小写敏感——'api' => [Hyperf\Validation\ValidationExceptionHandler::class],不能写成'API'或'http' - 若用了自定义 Handler,确保调用了
$throwable->validator->errors()->messages(),而不是只取first()
让协程报错堆栈完整显示出来
协程里抛异常,日志里只有 "Error: xxx",没有文件行号和调用链?那是日志格式器没启用堆栈追踪。
- 修改
config/autoload/logger.php,找到'formatter' => Monolog\Formatter\LineFormatter::class的'constructor'配置 - 把第四个参数设为 true(
include_stacktraces),第五个设为 true(allow_inline_line_breaks) - 重启服务后,任何未捕获异常都会带完整堆栈输出到日志,包括协程内触发的
给每条日志打上协程与请求标识
并发一高,几条请求的日志挤在一起,根本分不清哪条属于哪个请求——错误定位直接失效。
- 在控制器入口或中间件中手动注入唯一标识:
\Hyperf\Context\Context::set('correlation_id', uniqid('req_')); - 打印日志时显式带上上下文:
$this->logger->info('user login', ['cid' => \Swoole\Coroutine::getCid(), 'rid' => $request->getAttribute('request_id') ?? 'unknown']); - 避免依赖
$_SERVER或全局变量,协程环境下它们无法隔离










