hyperf生产环境需开启app_debug=true并配置exceptions.php中对应server name的validationexceptionhandler,确保验证错误返回errors字段且日志带协程上下文。

Hyperf 默认在生产环境关闭详细错误提示,避免敏感信息泄露。要开启异常错误提示,核心是改两处配置:一处控制是否显示错误详情,另一处决定是否返回完整堆栈和验证错误字段。
开启调试模式并启用错误详情
修改 config/autoload/exceptions.php 中的全局配置:
- 确保
'debug' => true已启用(该值通常由.env中的APP_DEBUG=true控制) - 检查
'handler'数组中对应 server name 的处理器是否为ValidationExceptionHandler(如'http' => [Hyperf\Validation\ValidationExceptionHandler::class]) - 确认该 handler 没有被更宽泛的自定义 handler 覆盖——它必须排在
HttpExceptionHandler之后,否则 422 验证错误会被降级成 500
确保验证失败返回 errors 字段
验证失败只返回 message 而没有 errors,多数因 handler 键名不匹配或逻辑缺失:
- 运行
php bin/hyperf.php start,查看启动日志中 HTTP server 的name(如[INFO] Server started: http://0.0.0.0:9501对应的 name 是http或api) - 打开
config/autoload/server.php,确认 HTTP server 的'name' => 'xxx'值 - 在
config/autoload/exceptions.php中,'handler'的键必须与上一步的 name 完全一致、大小写敏感(例如 name 是api,就得写'api' => [...]) - 若使用自定义
ValidationExceptionHandler,需确保 handle 方法里调用的是$throwable->validator->errors()->messages(),而非仅first()
让日志带上上下文便于追踪
光开 debug 不够,协程环境下日志容易混杂,需手动注入请求标识:
- 在
config/autoload/logger.php中,将LineFormatter的构造参数第四个设为true(启用include_stacktraces) - 在控制器入口或中间件中执行:
\Hyperf\Context\Context::set('correlation_id', uniqid('req_')); - 记录日志时显式传入上下文:
$this->logger->info('login start', ['cid' => \Swoole\Coroutine::getCid(), 'rid' => $request->getAttribute('request_id') ?? 'unknown']);
验证注解和中间件是否就位
如果连验证规则都不触发,可能是基础组件没注册:
- 确认已执行:
php bin/hyperf.php vendor:publish hyperf/validation和php bin/hyperf.php vendor:publish hyperf/translation - 检查
config/autoload/middlewares.php的http数组是否包含Hyperf\Validation\Middleware\ValidationMiddleware::class - 确认控制器方法上的
#[Validate]注解已正确引入:use Hyperf\Validation\Annotation\Validation;,且 rules 是合法 PHP 数组字面量(如rules={"email": "required|email"})











