graphql-request
graphql-request copied to clipboard
Global error handling on a graphql-request instance
Hi,
I am wondering if there is a way to handle errors globally?
For context, I am using graphql-request with graphql-code-gen SDK. I have a graphql-instance that I pass to the getSdk function i.e ;
const graphqlRequestInstance = new GraphQLClient(
`${process.env.NEXT_PUBLIC_BASE_API_URL}/${endpoint}`,
{
headers: {...},
}
);
const sdk = getSdk(graphqlRequestInstance);
...
I have one instance so that I don't have to configure the URL repeatedly, plus some headers for auth among others.
One of the scenarios I have is that the request might throw a 401 if the session has expired, and I'd need to handle that. How would I handle that in this kind of setup globally?
For example, when using axios I could do something like this;
axiosInstance.interceptors.response.use(
(response) => response,
async (error: AxiosError) => {
if (error?.response?.status === 401) {
//handle the 401 error
}
return Promise.reject(error);
}
);
I was coming from Axios as well and resolved this with an intermediary class:
class GraphqlClient {
private repository: Repository
private client: GraphQLClient
constructor(repository: Repository) {
this.repository = repository
this.client = new GraphQLClient("http://localhost:8080/graphql")
}
query<T = GraphqlQuery, V = Variables>(document: RequestDocument, variables?: V): Promise<T> {
return this.makeRequest<T, V>(document, variables)
}
mutation<T = GraphqlMutation, V = Variables>(
document: RequestDocument,
variables?: V,
): Promise<T> {
return this.makeRequest<T, V>(document, variables)
}
private makeRequest<T = GraphqlQuery, V = Variables>(
document: RequestDocument,
variables?: V,
): Promise<T> {
return new Promise((resolve, reject) => {
this.client
.request(document, variables, {
Authorization: `Bearer ${this.repository.session.getJwt()}`,
})
.then(resolve)
.catch((error: any) => {
const reqRes = JSON.parse(JSON.stringify(error))
return reject({ name: reqRes.response.errors[0].message })
})
})
}
}
And then you can use it like:
graphqlClient.query(...)
and globally have errors resolved in the same way. I use this to add the jwt to every request as well, and eventually log some things to the server as well, hence why I've also split the query and mutation functions.
@gabrielgatu, thanks for your response. Does your setup include using code-gen? If yes, is there a chance you can give a full example along with your custom graphql-client?
@joeynimu There's an example of how to do just that in the documentation: https://www.graphql-code-generator.com/docs/plugins/typescript-graphql-request#examples-of-middleware
But it's using polly-js. I would like to use it without that as I'm not interested in retries.
I also have this need
You can override fetch client https://github.com/prisma-labs/graphql-request#using-a-custom-fetch-method, which allows you to use something like https://www.npmjs.com/package/fetch-retry instead.