You need to enable JavaScript to run this app. Apollo Server中如何不中断resolver向errors数组添加错误并返回数据
优惠活动
大模型
产品
解决方案
定价
更多

Apollo Server中如何不中断resolver向errors数组添加错误并返回数据

需求可行性说明

该需求完全可以实现。Apollo Server支持在不中断Resolver执行、不抛出全局错误的前提下,将局部业务错误添加到响应的errors数组中,同时返回正常处理后的有效数据。

具体实现步骤

我们通常使用「上下文暂存错误+响应钩子合并」的方案实现,具体操作如下:

步骤1:初始化上下文时新增自定义错误存储字段

在Apollo Server的上下文创建逻辑中,新增一个空数组用于暂存非阻断的局部错误,同时配置响应格式化钩子合并错误:

// Apollo Server 4 配置示例
import { ApolloServer } from '@apollo/server';

const server = new ApolloServer({
  typeDefs,
  resolvers,
  // 配置响应格式化钩子,合并局部错误到官方errors数组
  async formatResponse(response, contextValue) {
    if (contextValue.partialErrors?.length) {
      response.errors = [...(response.errors || []), ...contextValue.partialErrors];
    }
    return response;
  }
});

// 上下文创建函数
async function createContext() {
  return {
    // 新增局部错误存储数组
    partialErrors: []
  };
}

步骤2:在Resolver中收集局部错误

处理数组遍历逻辑时,遇到不支持的条目直接创建GraphQLError实例存入上下文的partialErrors数组即可,不需要抛出错误,继续处理剩余有效条目:

import { GraphQLError } from 'graphql';

const resolvers = {
  Mutation: {
    batchProcessItems: async (_, { inputItems }, context) => {
      const processedResult = [];
      for (let i = 0; i < inputItems.length; i++) {
        const currentItem = inputItems[i];
        try {
          // 正常处理条目的业务逻辑
          const validResult = await processSingleItem(currentItem);
          processedResult.push(validResult);
        } catch (err) {
          // 捕获单条处理错误,存入局部错误数组,不中断整体执行
          context.partialErrors.push(new GraphQLError(
            `不支持的条目: ${err.message}`,
            {
              extensions: {
                code: 'UNSUPPORTED_ITEM',
                itemIndex: i, // 标注错误对应条目的索引,方便客户端定位
                itemId: currentItem.id
              }
            }
          ));
        }
      }
      // 直接返回所有有效条目的处理结果
      return { processedItems: processedResult };
    }
  }
};

可选方案:Schema内置错误字段

如果希望业务错误和全局系统错误完全隔离,也可以直接在返回类型中定义业务错误字段,不需要修改Apollo Server的钩子配置:

# Schema定义示例
type ProcessItemError {
  message: String!
  itemIndex: Int!
  itemId: ID
}

type BatchProcessResult {
  processedItems: [ProcessedItem!]!
  itemErrors: [ProcessItemError!]!
}

type Mutation {
  batchProcessItems(inputItems: [ItemInput!]!): BatchProcessResult!
}

Resolver处理逻辑和上述逻辑一致,只是把错误收集到返回值的itemErrors字段即可。

注意事项
  • 每个局部错误都需要添加足够的标识信息(比如条目索引、ID),避免客户端无法关联错误和对应条目
  • 合并错误到官方errors数组时要保留原有全局错误,不要直接覆盖
  • 不要在Resolver中抛出错误,一旦抛出错误会中断Resolver执行,无法返回有效数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 12:54:05