使用graphql-js和express实现自定义错误时属性丢失问题求助
解决自定义GraphQL错误属性在formatError中丢失的问题
我之前也踩过一模一样的坑!当你在GraphQL和express-graphql里自定义错误时,属性丢失大概率是因为GraphQL的错误序列化机制只默认保留标准字段,自定义属性如果没放在正确的位置,就会在传递过程中被丢弃。不管你继承Error还是GraphQLError,核心问题都是这个——我来给你拆解解决方案:
1. 正确封装自定义错误类
你需要把自定义属性放在GraphQLError的extensions参数里,而不是直接挂载到错误实例上。示例代码如下:
const { GraphQLError } = require('graphql'); // 自定义权限错误类 class CustomAuthError extends GraphQLError { constructor(message, customData) { super(message, { extensions: { code: 'UNAUTHENTICATED', // 标准错误码 customProperty: customData, // 你的自定义属性 // 可以添加更多自定义字段 } }); // 给错误实例设置name,方便调试 Object.defineProperty(this, 'name', { value: 'CustomAuthError' }); } }
为什么要这么做?因为GraphQL在处理错误时,只会把extensions里的内容序列化后传递给formatError,直接挂在实例上的属性会被过滤掉。
2. 在formatError中正确读取自定义属性
接下来要确保你的formatError函数从err.extensions里提取自定义字段,而不是直接从err实例上取。示例express-graphql配置:
const { graphqlHTTP } = require('express-graphql'); app.use('/graphql', graphqlHTTP({ schema: yourGraphQLSchema, graphiql: true, formatError: (err) => { // 从extensions中解构出自定义属性 const { customProperty, code, ...rest } = err.extensions || {}; // 返回你需要的错误结构 return { message: err.message, errorCode: code, customData: customProperty, locations: err.locations, path: err.path }; } }));
现在再打印formatError里的自定义属性,就不会是undefined了。
3. 排查常见误区
- 不要直接继承原生Error:如果你用
class CustomError extends Error,GraphQL会把它包装成一个默认的GraphQLError,你的自定义属性会全部丢失,必须继承GraphQLError才能正确传递extensions。 - 检查依赖版本:如果你的
express-graphql版本低于0.12.0,或者graphql版本低于15.x,对extensions的支持可能有问题,建议升级到最新稳定版。 - 确保抛出的是自定义错误实例:比如在resolver里要写
throw new CustomAuthError('无权访问', { userId: 123 }),而不是throw new Error('无权访问')。
按照这个方式调整后,你的自定义属性应该就能正常出现在formatError里了!
内容的提问来源于stack exchange,提问作者Johannes Merz
相关产品推荐
相关产品推荐

