React-Apollo catch when server is down

Viewed 825

In my React ApolloGraphQL app with a node server, I'm trying to have it catch errors when my node server is down. All works great and normal when the node server us up... graphQL errors are caught and displayed. But when I stop the node server, I get a runtime error that I can't avoid. When the node server is down, the server responds with a 503 Service Unavailable response and an html page that isn't JSON.

The apollo client is set up like this:

const client = new ApolloClient({
  assumeImmutableResults: true,
  fetchOptions: {
    credentials: "include"
  },
  fetch: fetch,
  onError: ({ graphQLErrors, networkError }) => {
    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 = {errors:null};
  },
  cache: new InMemoryCache({
    freezeResults: true,
    dataIdFromObject: obj => {
      let dataId = null;
      switch (obj.__typename) {
        default:
          dataId = defaultDataIdFromObject(obj);
      }
      return dataId;
    },
    cacheRedirects: {
      Query: {
        productVariant: (_, args, { getCacheKey }) => {
          const cacheKey = getCacheKey({ __typename: "ProductVariant", ...args });
          return cacheKey;
        }
      }
    },
  }),
});

The above onError block response with this message:

Error: Network error: JSON.parse: unexpected character at line 1 column 1 of the JSON data

I have the mutation set up this way:

const [mutateVariant, {data, error, loading}] = useMutation(UPDATE_PRODUCT_META);

And I call it like so:

mutateVariant({ variables: {inputM: {...buildMetaInput(editedData)} }, 
    errorPolicy: 'ignore', onError: (error) => Logger("Error:", error)});

You can see I've tried it with different errorPolicy settings and adding an onError callback.

But I keep getting unhandled runtime errors and don't seem to be able to catch and handle them:

Unhandled Runtime Error

Error: Network error: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Call Stack
ApolloError           webpack-internal:///./node_modules/apollo-client/bundle.esm.js (76:28)
error                 webpack-internal:///./node_modules/apollo-client/bundle.esm.js (1041:48)
notifySubscription    webpack-internal:///./node_modules/zen-observable/lib/Observable.js (140:18)
onNotify              webpack-internal:///./node_modules/zen-observable/lib/Observable.js (179:21)
error                 webpack-internal:///./node_modules/zen-observable/lib/Observable.js (240:15)
error/<               webpack-internal:///./node_modules/apollo-client/bundle.esm.js (880:76)
error                 webpack-internal:///./node_modules/apollo-client/bundle.esm.js (880:27)
notifySubscription    webpack-internal:///./node_modules/zen-observable/lib/Observable.js (140:18)
onNotify              webpack-internal:///./node_modules/zen-observable/lib/Observable.js (179:21)
error                 webpack-internal:///./node_modules/zen-observable/lib/Observable.js (240:15)
error                 webpack-internal:///./node_modules/apollo-link-error/lib/bundle.esm.js (53:34)
notifySubscription    webpack-internal:///./node_modules/zen-observable/lib/Observable.js (140:18)
onNotify              webpack-internal:///./node_modules/zen-observable/lib/Observable.js (179:21)
error                 webpack-internal:///./node_modules/zen-observable/lib/Observable.js (240:15)
createHttpLink/</</<  webpack-internal:///./node_modules/apollo-link-http/lib/bundle.esm.js (92:26)

the returned error data from the useMutation hook:

graphQLErrors: Array []
message: "Network error: JSON.parse: unexpected character at line 1 column 1 of the JSON data"
​networkError: {…}
​  ​bodyText: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>503 Service 
  Unavailable</title>\n</head><body>\n<h1>Service Unavailable</h1>\n<p>The server is temporarily unable 
  to service your\nrequest due to maintenance downtime or capacity\nproblems. Please try again later.  
  </p>\n<p>Additionally, a 503 Service Unavailable\nerror was encountered while trying to use an 
  ErrorDocument to handle the request.</p>\n</body></html>\n"
  name: "ServerParseError"
​​  response: Object {  }
​​  statusCode: 503

How do I catch this error?

1 Answers

The mutateVariant function returns a promise. Try adding a .catch() after it is called.

mutateVariant().catch(() => {...});
Related