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
相关产品推荐
相关产品推荐

