Fastify错误处理器调用reply.code()返回原始错误问题
现象产生原因
核心是取值逻辑错误加Fastify错误处理机制共同导致:
- 状态码取值非法:你在
processError末尾调用res.code()时,传入的是Number(err?.code || err?.statusCode || 500),但err.code字段并不全是HTTP状态码:比如数据库错误的code是23505这类数据库自身的错误标识字符串、Schema校验错误的code是FST_ERR_VALIDATION这类Fastify内部错误字符串,强转Number后要么是超出HTTP合法状态码范围(100-599)的超大数字,要么是NaN。Fastify接收到非法状态码时,会判定当前自定义错误处理器执行异常,自动回退到内置错误处理逻辑,直接序列化返回原始入参的err对象,忽略你return的processedError。 - 状态码被重复覆盖:你在
processDatabaseError、processSchemaValidationError这类专项处理函数中,已经根据错误类型调用res.code()设置了正确的HTTP状态码(比如409、400),但末尾的统一res.code调用会把之前设置好的正确状态码覆盖掉,就算取值合法也不符合预期。
修复方案
调整状态码设置逻辑,只在专项处理未命中、没有提前设置状态码时走兜底逻辑,不要全局覆盖已经设置好的状态码,同时修正状态码取值规则,避免把数据库错误码、框架内部错误码当成HTTP状态码传入:
export default async function processError( err: FastifyError, req: FastifyRequest, res: FastifyReply ): Promise<FastifyError | TErrorReply> { console.log({ err: err.stack }); let processedError: TErrorReply = err; if (isDatabaseError(err)) processedError = processDatabaseError(req, res, err); if (isSchemaValidationError(err)) processedError = processSchemaValidationError(req, res, err); if (process.env.NODE_ENV === 'development') processedError = { ...processedError, stack: err.stack || new Error().stack, }; console.log({ processedError }); // 仅当专项处理未设置有效状态码(reply默认状态码为200)时,才设置兜底状态码 if (res.statusCode === 200) { // 仅取用err上标注的HTTP状态码字段statusCode,忽略非HTTP的错误标识code const fallbackCode = Number.isInteger(err.statusCode) ? err.statusCode : 500; res.code(fallbackCode); } return processedError; }
调整后专项处理函数设置的409、400等正确状态码会被保留,未命中专项处理的错误会自动返回兜底的500或错误自带的合法HTTP状态码,同时自定义格式化的processedError会被正常作为响应体返回。
内容的提问来源于stack exchange,提问作者Sap Green
相关产品推荐
相关产品推荐

