Apollo Server抛出错误未在响应中显示的TypeScript解决方案
解决Apollo Server错误无法返回至响应的问题
你遇到的问题是Apollo Server 3.x的默认行为导致的:生产环境下它会隐藏错误详情,仅返回对应字段为null,且未正确捕获的错误可能导致服务器崩溃。以下是具体解决步骤:
1. 开发环境开启Debug模式
在ApolloServer初始化时添加debug配置,开发环境下会返回完整错误信息:
const server = new ApolloServer({ typeDefs, resolvers, context: createContext, debug: process.env.NODE_ENV !== 'production', // 仅开发环境开启 });
2. 规范使用Apollo/GraphQL错误类
别用原生Error,直接用ApolloError或GraphQLError抛出,确保错误被Apollo正确识别:
import { ApolloError } from 'apollo-server-express'; // 或者用GraphQL官方错误类 import { GraphQLError } from 'graphql'; // 在Resolver里这么抛 async function cprofile(_, { input }) { // 业务逻辑出错时 throw new ApolloError('测试错误', 'USER_INPUT_ERROR', { input }); // 或者更灵活的GraphQLError throw new GraphQLError('参数错误', { extensions: { code: 'INVALID_INPUT', http: { status: 400 }, details: input, }, }); }
3. 自定义错误格式化函数
通过formatError配置,控制错误返回的内容,开发环境显示详情,生产环境返回友好提示:
const server = new ApolloServer({ // ...其他配置 formatError: (err) => { if (process.env.NODE_ENV === 'production') { return new ApolloError('服务器内部错误', 'INTERNAL_ERROR'); } // 开发环境返回完整错误信息 return { message: err.message, code: err.extensions?.code || 'UNKNOWN', path: err.path, locations: err.locations, details: err.extensions, }; }, });
4. 确保Resolver错误不被吞掉
异步Resolver里如果用了try/catch,一定要重新抛出错误,不然Apollo捕获不到:
// 错误写法:吞掉错误 async function badResolver() { try { // 业务逻辑 throw new Error('test'); } catch (err) { console.log(err); // 只打日志不抛出,Apollo以为没出错 } } // 正确写法:重新抛出 async function goodResolver() { try { // 业务逻辑 throw new Error('test'); } catch (err) { throw new ApolloError(err.message, 'BUSINESS_ERROR'); } }
5. 检查Express集成的启动流程
如果是和Express一起用,必须先调用server.start()再挂载中间件,否则错误处理会异常:
async function bootstrap() { const app = express(); await server.start(); // 这步不能少 server.applyMiddleware({ app }); app.listen(4000, () => { console.log(`服务启动在 http://localhost:4000${server.graphqlPath}`); }); } bootstrap();
做完这些配置后,再发送mutation请求,错误就会出现在响应的errors数组里,而不是仅返回null了。
内容的提问来源于stack exchange,提问作者Jonathan Coletti
相关产品推荐
相关产品推荐

