1

I am creating an React app using Apollo Graphql and I am having some trouble with the Apollo Link Rest. The problem is that in the middle of my app I have to make a REST request, however this request can be sucessful and return a status code = 200 or it can fail, returning a status code = 400.

It is important for my app to show the end user an error message that is returned in this request's body in case of a 400 error. However when an error happens the Apollo Link Rest just throws an exception, but it doesn't return response body back to me.

Is there a way for me to get the response body, when there is an error with the Apollo Link Rest? I thought that I could get it from the result variable, but since the Apollo throws an exception, this variable never changes.

Here is my code:

    const result = await context.client.query<MyQuery>({
      query: MyQuery,
      variables: {
        input: {
          companyId: variables.companyId,
        },
      },
    });
query MyQuery($input: MyQueryInput!) {
  myQuery(input: $input) @rest(
    type: "QueryResponse",
    method: "POST"
    path: "v1/my-query"
  ) {
    id
    minimumPreparationTime
    maximumPreparationTime
    extras {
      id
      optional
      key
    }

    warning
    error {
      id
      type
      message
    }
  }
}
Felipe
  • 6,312
  • 11
  • 52
  • 70

2 Answers2

3

Extending Greg comment and apollo-link-error, you can retrieve the error body from networkError.result.message.

0

You can use apollo-link-error to catch and handle server errors, network errors, and GraphQL errors. You should be able to conditionally set response.errors if needed.

    import { onError } from "apollo-link-error";

    const link = onError(({ graphQLErrors, networkError, response, operation }) => 
    {
       if (graphQLErrors)
       graphQLErrors.map(({ message, locations, path }) =>
           console.log(
            `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: 
            ${path}`,
          ),
        );

     if (networkError) console.log(`[Network error]: ${networkError}`);

    response.error = // set error property here 
});

It may also be worth noting Apollo exposes an errorPolicy option, for which the default is none. The policy can be modified to all which, according to the docs,

is the best way to notify your users of potential issues while still showing as much data as possible from your server. It saves both data and errors into the Apollo Cache so your UI can use them.

Greg Brodzik
  • 1,765
  • 7
  • 9
  • I've tried all three error policies, but they didn't work. I also tried to set the response object as you suggested, but it is null, so I created a new one as: `response = { error: networkError }`, but that also didn't work. – Felipe Oct 04 '19 at 19:59
  • For now I decided that I will use `fetch` for more complicated REST requests and update the Apollo Cache manually. – Felipe Oct 04 '19 at 20:00
  • Given none of those worked, you might want to consider setting up a *local* resolver using the @client directive offered by Apollo’s local state management tool. Within the local resolver you could make the network request to your rest endpoint. The nice part about this approach is that you have flexibility to merge the local resolver (data retrieved from your rest endpoint in this case) with data resolved from your main graph endpoint in a single query. Can take a look at the docs here: https://www.apollographql.com/docs/react/data/local-state/ – Greg Brodzik Oct 06 '19 at 04:21
  • Well in the end I did exactly that. I created a new local `@client` resolver that makes this request using `fetch`. I then update the Apollo In Memory Cache manually. – Felipe Oct 07 '19 at 13:13