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

Apollo Server如何同时返回错误信息与数据?

在Apollo中手动返回部分数据与混合错误负载

要实现你需要的「返回部分有效变更数据,同时将验证错误放入errors.extensions.validationErrors」的需求,核心思路是避免在顶层解析器中抛出错误(否则会截断数据返回),而是通过上下文收集错误,再利用Apollo Server的formatError钩子将错误注入响应的errors数组,具体步骤如下:

1. 在解析器中收集错误并返回有效数据

在mutateEntities的解析器里,遍历输入数组分别处理每个实体:验证通过的执行变更并收集结果,验证失败的将错误暂存到请求上下文中,最后直接返回有效结果,不要抛出任何错误。

示例伪代码:

const resolvers = {
  Mutation: {
    mutateEntities: async (_, { mutateEntities }, context) => {
      const validResults = [];
      // 初始化上下文的错误收集容器
      context.validationErrors = [];

      for (const input of mutateEntities) {
        try {
          // 执行你的实体验证逻辑
          validateEntityInput(input);
          // 验证通过,执行变更操作
          const mutationResult = await executeEntityMutation(input);
          validResults.push(mutationResult);
        } catch (validationErr) {
          // 收集验证失败的实体错误
          context.validationErrors.push({
            entityType: input.type,
            entityId: input.id,
            message: validationErr.message,
            details: validationErr.details
          });
        }
      }

      // 直接返回有效结果,不抛错
      return validResults;
    }
  }
};

2. 配置formatError钩子注入自定义错误

在Apollo Server的配置中,添加formatError函数,检查上下文中是否有收集到的验证错误,若有则构造符合要求的错误对象加入响应的errors数组:

const server = new ApolloServer({
  typeDefs,
  resolvers,
  formatError: (formattedError, { context }) => {
    // 仅当上下文存在验证错误时,构造自定义错误
    if (context?.validationErrors?.length > 0) {
      return {
        message: "部分实体变更失败",
        extensions: {
          code: "PARTIAL_VALIDATION_FAILURE",
          validationErrors: context.validationErrors
        }
      };
    }
    // 其他类型的错误保持原有格式返回
    return formattedError;
  }
});

3. 最终响应格式

这样处理后,你会得到符合预期的响应:

{
  "data": {
    "mutateEntities": [
      {"id": "entityA", "status": "success"},
      {"id": "entityB", "status": "success"}
    ]
  },
  "errors": [
    {
      "message": "部分实体变更失败",
      "extensions": {
        "code": "PARTIAL_VALIDATION_FAILURE",
        "validationErrors": [
          {"entityId": "entityC", "message": "格式错误:缺少必填字段"},
          {"entityId": "entityD", "message": "格式错误:类型不匹配"}
        ]
      }
    }
  ]
}

关键注意点

  • 绝对不要在顶层解析器抛错:一旦抛出错误,Apollo会默认清空data字段,导致无法返回有效数据
  • 错误信息要精准:在validationErrors中带上实体的唯一标识(如ID),方便前端对应到具体输入项
  • 对齐前端逻辑:确保extensions中的字段名(比如validationErrors)和前端现有错误处理逻辑完全一致,无需修改前端代码

内容的提问来源于stack exchange,提问作者Supperhero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:05:26