🚀

apollo clientでエラーの時のステータスコードを取り出す

2022/02/18に公開

背景

GraphQLではエラー時でもステータスコードは200でerrorをレスポンスのボディに詰めて返すことが推奨されている

が、認証エラーなどはサーバー側の実装の都合でGraphQLのレイヤーまでいかずにレスポンスを返すことがあると思う。

今回はそういうケースで、レスポンスのステータスコードでメッセージを出し分けたかったが、少し嵌ったのでそのメモ

Apolloの公式ドキュメントではレスポンスの error.networkError からステータスコードを取得できると記述されていた

で、実際に取得しようと試みるも

補完に出てこない...

そこで、コードを追ってみると レスポンスには必ずしも statusCode というプロパティが含まれた値が返ってくると限らないことがわかった。

   public networkError: Error | ServerParseError | ServerError | null;

https://github.com/apollographql/apollo-client/blob/main/src/errors/index.ts#L48

ServerParseErrorとServerErrorの時のみstatusCodeが含まれてることがわかった

  • ServerParseError
export type ServerParseError = Error & {
  response: Response;
  statusCode: number;
  bodyText: string;
};

https://github.com/apollographql/apollo-client/blob/main/src/link/http/parseAndCheckHttpResponse.ts#L8

  • ServerError
export type ServerError = Error & {
  response: Response;
  result: Record<string, any>;
  statusCode: number;
};

https://github.com/apollographql/apollo-client/blob/main/src/link/utils/throwServerError.ts#L4

解決策

以下のようにcastしてあげたら問題なく取り出せた

if (error.networkError?.name === 'ServerParseError' || error.networkError?.name === 'ServerError') {
    let parseErrorStatusCode = (error.networkError as ServerParseError).statusCode
    let serverErrorStatusCode = (error.networkError as ServerError).statusCode
}

tsだとcastしてあげないといけないので何が返ってくるか確認しないと嵌まりますね。以上。

Discussion