Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client throwing error instead of returning error in query #12219

Open
brunomgurgel opened this issue Dec 12, 2024 · 4 comments
Open

Client throwing error instead of returning error in query #12219

brunomgurgel opened this issue Dec 12, 2024 · 4 comments

Comments

@brunomgurgel
Copy link

brunomgurgel commented Dec 12, 2024

I'm setting up Graphql on my app but I'm facing an issue where the client throws an error if the api call fails instead of returning in the query.errors property. One important note is that I'm fetching data in a React Server Component

Versions:

Next.js - 14.2.11
React - 18.3.1
@apollo/client- 3.12.2,
@apollo/experimental-nextjs-app-support - 0.11.7,

Here is how I am registering the client:

export const { getClient, query, PreloadQuery } = registerApolloClient(() => {
  const token = getAuthToken();

  return new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({
      // this needs to be an absolute url, as relative urls cannot be used in SSR
      uri: env.INTERNAL_GRAPHQL_URL,
      // you can disable result caching here if you want to
      // (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
      // fetchOptions: { cache: "no-store" },
      credentials: 'same-origin',
      headers: {
        Authorization: `Bearer ${token}`,
      },
    }),
    name: 'enterprise-apps-corporate',
  });
});

And here is how I'm fetching data:

try {
     // This is throwing
      const query = await getClient().query({
        query: MY_QUERY,
        variables: { foo: 'bar' },
      });

      if (query.errors) {
        const errorResponse = this.handleGraphQLError('Failed to query data', query.errors);

        if (errorResponse) {
          return errorResponse;
        }
      }

      return {
        ...query,
        status: ResponseStatus.Success,
      };
    } catch (error) {
      if (isGraphqlError(error)) {
        const errorResponse = this.handleGraphQLError('Failed to query data', error.graphQLErrors);

        if (errorResponse) {
          return errorResponse;
        }
      }

      return {
        data: undefined,
        errors: [error] as Error[],
        status: ResponseStatus.InternalServerError,
      };
    }

Any help would be really appreciated!

@phryneas
Copy link
Member

phryneas commented Dec 13, 2024

This is a difference between the ApolloClient.prototype.query imperative function and the useQuery hook that we probably have to document better.

Since this is a core Apollo Client issue, I'm moving it over to https://github.com/apollographql/apollo-client

@phryneas phryneas transferred this issue from apollographql/apollo-client-nextjs Dec 13, 2024
Copy link

triagster bot commented Dec 13, 2024

Related issues:

Was this useful? Use the thumbs up or thumbs down reaction to give feedback.

@phryneas
Copy link
Member

phryneas commented Dec 13, 2024

This is hinted at in the docblock of ApolloClient.error, but I admit it could be clearer:

https://www.apollographql.com/docs/react/api/core/ApolloClient#query
This resolves a single query according to the options specified and returns a Promise which is either resolved with the resulting data or rejected with an error.

I'll try to make a table here:

api client.query client.watchQuery useQuery hook
errorPolicy
"none" (default) throws error throws error is graphQLErrors? populates result.errors and result.error
otherwise (e.g. link error), throw
"ignore" is graphQLErrors? act as if there is no error
otherwise (e.g. link error), throw
is graphQLErrors? act as if there is no error
otherwise (e.g. link error), throw
is graphQLErrors? act as if there is no error
otherwise (e.g. link error), throw
"all" is graphQLErrors? populates result.errors
otherwise (e.g. link error), throw
is graphQLErrors? populates result.errors
otherwise (e.g. link error), throw
is graphQLErrors? populates result.errors and result.error
otherwise (e.g. link error), throw

I'd reduce it to these rules:

  • errors that are not part of the network response (graphQLErrors) will always throw
  • graphQLErrors are handled as per GraphQL error policies
  • special case in the useQuery hook: a graphQLError that would throw will also populate the errors property instead, as expected errors should not be thrown in non-suspense hooks
  • the useQuery hook will also populate result.error if there is result.errors

@brunomgurgel
Copy link
Author

Thank you for the explanation @phryneas !! This is really helpful

@github-actions github-actions bot removed the 🏓 awaiting-contributor-response requires input from a contributor label Dec 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants