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 },
});
