ค้นหาเว็บไซต์

typescript - กับ Apollo Server v4, จะเข้าถึง context ในการจัดการข้อผิดพลาดอย่างไร?


ฉันกำลังอัปเกรด Apollo Server ของฉันเป็นเวอร์ชัน 4 ในโปรเจ็กต์ Typescript ฉันกำลังใช้ middleware ของ 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

มันไม่ใช่วิธีที่สมบูรณ์แบบ แต่ถ้าคุณพยายามข้ามการบล็อกในวันนี้ ขึ้นอยู่กับวิธีที่คุณส่งข้อผิดพลาด คุณสามารถเพิ่มข้อมูลเพิ่มเติมลงในข้อผิดพลาดเองได้ ตัวอย่างเช่น ถ้าคุณใช้ 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 },
});