NestJS 的 GraphQL Error
筆記一下 NestJS (搭配 Apollo) 是怎麼把內部丟出的 exception 轉換成 GraphQL 的 error response。
標準步驟
階段 1. Apollo server
- 如果 exception 不是
GraphQLError,會先將 resolver 丟出的 exception 包裝在GraphQLError的originalError裡面。 - 取用(轉換後的)
GraphQLError.extensions的code和http,產出第一階段的 error response (GraphQLFormattedError):- 如果沒有
code,會使用INTERNAL_SERVER_ERROR作為預設值 http如果有status,必須是數字,會影響 HTTP 回應的狀態碼http如果有headers,必須是Map物件
- 如果沒有
- 將
GraphQLFormattedError丟給formatError選項,產出新的 error response
階段 2. NestJS Apollo driver
(透過 Apollo server 的 formatError 選項改寫 error response)
- 如果拿到的
GraphQLError.originalError不是 NestJS 的HttpException,不做改寫; - 改寫方式:
- 將原本 HttpExcpetion 的
.response塞在 output 的.extensions.originalError欄位 - 如果
HttpException是 400、401、403 之一,會修改.extensions.code為對應的值。範例:1{ 2 "errors": [ 3 { 4 "message": "....", 5 "extensions": { 6 "code": "BAD_REQUEST", 7 "originalError": { 8 "message": "...." 9 "error": "Bad Request" 10 "statusCode": 400 11 } 12 } 13 } 14 ], 15 "data": null 16} - 如果不是,則保留
INTERNAL_SERVER_ERROR作為預設值,新增.extensions.status欄位來表示 HTTP 狀態碼。例如:1{ 2 "errors": [ 3 { 4 "message": "", 5 "extensions": { 6 "code": "INTERNAL_SERVER_ERROR", 7 "status": 404, 8 "originalError": { 9 "message": "...." 10 "error": "Not Found" 11 "statusCode": 404 12 } 13 } 14 } 15 ], 16 "data": null 17}
- 將原本 HttpExcpetion 的
客製化方法
想要改寫 HTTP status / header: 丟出
GraphQLError,在extensions裡面新增http欄位只有要改寫 error response 的內容: 透過 GraphQLModule 的
formatError選項