GithubHelp home page GithubHelp logo

Comments (5)

nikolay-emrikh-stenn avatar nikolay-emrikh-stenn commented on June 20, 2024 1

I've created function to determine if thrown error is a graphql-endpoint error (isGraphQLEndpointError):

export const isErrorWithResponse = (error: Error): error is Error & { response: GraphQLClientResponse<unknown> } =>
    error.hasOwnProperty('response');

export const isGraphQLEndpointError = (error: unknown): error is Error & { response: GraphQLClientResponse<unknown> } =>
    error instanceof Error && isErrorWithResponse(error) && !!error.response.errors?.length;

And use it in react-query client to check whenever it needs to be retried or not, like this:

const queryClient = new QueryClient({
    defaultOptions: {
        queries: {
            retry: (retryCount, error) => {
                if (isGraphQLEndpointError(error)) {
                    // graphql endpoint is available and the problem occurred during the execution of the request
                    // and not due to infrastructure problems on the backend or network problems of the client
                    // so we don't need to retry as result will be same
                    return false;
                }
                return retryCount < 3;
            },
        },
    },
});

And in responseMiddleware i show toast with message:

// wrong type of argument
// it's not `GraphQLClientResponse<unknown> | Error`
// but `Error & { response: GraphQLClientResponse<unknown> }`
responseMiddleware: async (res) => {
    if (res instanceof Error) {
        if (isErrorWithResponse(res)) {
            res.response.errors?.forEach((error) => enqueueError(error.message));
        } else {
            enqueueError(res.message);
        }
    }
},

from graphql-request.

nikolay-emrikh-stenn avatar nikolay-emrikh-stenn commented on June 20, 2024

By the way _response is an instance of Error so can be checked with instanceof operator

const isErrorWithResponse = (error: Error): error is Error & { response: GraphQLClientResponse<unknown> } =>
    error.hasOwnProperty('response');

responseMiddleware: async (res) => {
    if (res instanceof Error) {
        if (isErrorWithResponse(res)) {
           res.response.errors?.map(...)
        } else {
            // just error
        }
    }
},

from graphql-request.

d-lasagno avatar d-lasagno commented on June 20, 2024

Thank you for the clarification. So if I understand this correctly, when the response it's a graphql error, _response is an instance of Error? For http errors it still is an error, but doesn't have the response field, right?

from graphql-request.

nikolay-emrikh-stenn avatar nikolay-emrikh-stenn commented on June 20, 2024

As i see it's always an instance of Error
But when it's graphql endpoint error theres additional response.errors field

But you pointed out correctly that types are wrong

So argument in responseMiddleware is not of type GraphQLClientResponse<unknown> | Error but of type Error & { response: GraphQLClientResponse<unknown> }

from graphql-request.

jonkoops avatar jonkoops commented on June 20, 2024

I don't think this is actually a bug, the response argument is one of three types:

  • GraphQLClientResponse — A valid response object containing the retrieved data.
  • ClientError — An error response that contains information about the underlying request and response.
  • Error — A generic error caused by something else than the network layer.

Putting all of that together you could write your error handling as follows:

const graphQLClient = new GraphQLClient(endpoint, {
  responseMiddleware(response) {
    if (response instanceof ClientError) {
      console.error('A client error occurred:', response);
      return;
    }
    
    if (response instanceof Error) {
      console.error('Some other error occurred:', response);
      return;
    }

    console.log('Got a valid response', response);
  }
});

from graphql-request.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.