使用Apollo Server v4,如何在错误处理中访问上下文(context)?

3

我目前正在将我的Apollo Server升级到TypeScript项目中的v4版本。我正在使用Express中间件来运行它。

现在让我困扰的是错误处理。

我想在将错误消息发送给客户端之前翻译它。为此,我需要访问包含用户语言的查询上下文。

在v3中,我过去会使用formatResponse来实现这一点。 现在在v4中,formatResponse已不复存在,并且根据迁移指南,我必须使用一个带有willSendResponse的插件,如下所示:

const responseFormattingPlugin: ApolloServerPlugin<MyContextType> = {
    async requestDidStart() {
        return {
            async willSendResponse(requestContext) {
                const {response, contextValue, errors} = requestContext;

                // Format reponse here. Unfortunately, errors is readonly                
            }
        };
    }
};

因此,我尝试使用formatError函数,但不幸的是,在这里我无法访问请求上下文,因此我不能做我想做的事情。
谢谢您的帮助!
1个回答

1

虽然不完美,但如果你今天需要绕过一个障碍,根据你如何抛出错误,你可以向错误本身添加额外信息。例如,如果你使用GraphQLError,你可以这样做:

throw new GraphQLError('some message', {
  extensions: { locale: context.local },
}

然后:

import { unwrapResolverError } from '@apollo/server/errors';

const server = new ApolloServer({
  formatError: (formattedError, error) => {
    if (formattedError?.extensions?.locale)) {
      return {
        ...formattedError,
        message: i18n(formattedError.message),
      };
    }
    return formattedError;
  },
  // ...
});

显然,这样做不太方便到处使用,但您可以通过在请求开始时将其作为类扩展到context对象中,然后只需抛出那个
const { url } = await startStandaloneServer(server, {
  context: async ({ req }) => {
    class LocalizedError extends GraphQLError {
      constructor(message: string, options: GraphQLErrorOptions = {}) {
        super(message, {
          locale: req.headers["accept-language"],
          ...options,
        });
      }
    }
    // throw new context.LocalizedError('some.i18n.key')
    return {
      ...whateverElse,
      LocalizedError,
    };
  },
  listen: { port: 4000 },
});

1
这看起来确实是最好的方法(也许是唯一的方法?)。我仍在努力找出在我的五年代码库中对throws影响最小的最佳方法。感谢您的建议! - Tdy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接