You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fastify错误处理器调用reply.code()返回原始错误问题

现象产生原因

核心是取值逻辑错误加Fastify错误处理机制共同导致:

  1. 状态码取值非法:你在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。
  2. 状态码被重复覆盖:你在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:45:30