🤔

graphql-requestのエラーの型が分からない

2022/12/09に公開

Next.js v13でGraphQLをpromiseで使うためにgraphql-requestを使っているのですが、エラーの型が分からなかったのでメモ。
typed-document-nodeで記述しています。

graphql-request
const Component = () => {
  
  const handleMutate = async () => {
    try {
      await new GraphQLClient('').request(HogeDocument).catch((e) => {
        e // any
      })
    } catch (e) {
      e // unknown
    }
  }
}

URQL

CombinedErrorを使って判定が可能。
返り値にerrorが含まれるのでcatchでキャッチする必要はない。
https://formidable.com/open-source/urql/docs/api/core/#combinederror

URQL
const Component = () => {
  const [,muattion] = useMutation(HogeDocument)

  const handleMutate = async () => {
    try {
      const { error } = await mutate()
      if (error) {
        error.graphQLErrors // GraphQLError[] 
      }
    } catch (e) {
      console.log(e) // その他のエラー
    }
  }
}

Apollo Client

ApolloErrorを使って判定が可能。
返り値にerrorを含むしcatchでも取得できる。
https://github.com/apollographql/apollo-client/blob/main/src/errors/index.ts#L44

Apollo Client
const Component = () => {
  const [mutate] = useMutation(HogeDocument)
  
  const handleMutate = async () => {
    try {
      const { error } = await mutate()
      if(errors) {
        errors  // ReadonlyArray<GraphQLError>
      }
    } catch (e) {
      if (e instanceof ApolloError) {
        e.graphQLErrors // ReadonlyArray<GraphQLError>
      }
    }
  }
}

graphql-request

GraphQLのエラーは200で返ってくるのにcatchできるので何かしらエラーの加工をしているっぽい。

https://github.com/prisma-labs/graphql-request#error-handling
https://github.com/prisma-labs/graphql-request/blob/master/examples/error-handling.ts#L23-L26
しかし、公式のError handlingの項目を見てもconsole.error(JSON.stringify(error, undefined, 2))としか書いておらず、型が分からない。

src/types.tsを見てみると、GraphQLResponseerrorの型がGraphQLErrorとなっている。
https://github.com/prisma-labs/graphql-request/blob/c17f82138e5c0e7960fd1fb2ba9ef439323d57dc/src/types.ts#L14-L20

このGraphQLResponseが使われている箇所を探すとClientErrorにたどり着いたので、ClientErrorinstanceofで判定するとほしい型が手に入りそうだった。
https://github.com/prisma-labs/graphql-request/blob/master/src/types.ts#L27-L28

const Component = () => {
  
  const handleMutate = async () => {
    try {
      await new GraphQLClient('').request(HogeDocument).catch((e) => {
        if (e instanceof ClientError) {
          e.response.errors // GraphQLError[] | undefined
        }
      })
    } catch (e) {
      if (e instanceof ClientError) {
        e.response.errors // GraphQLError[] | undefined
      }
    }
  }
}

errorClientErrorinstanceofで判定した後、e.response.errorsにアクセスするとGraphQLError[]orundefinedが取得できる。

Discussion