Apollo-link: Catching errors using links

Created on 2 Nov 2017  ·  5Comments  ·  Source: apollographql/apollo-link

Using this example from the documentation results into calling fetch 2 times (first one on subscribe and the second one in http link):

http://apollo-link-docs.netlify.com/docs/link/stateless.html

const reportErrors = (errorCallback) => new ApolloLink((operation, forward) => {
  const observer = forward(operation);
  // errors will be sent to the errorCallback
  observer.subscribe({ error: errorCallback })
  return observer;
});

//...

const createLinks = () =>
  ApolloLink.from([
    reportErrors(console.error),
    httpLink,
  ]);

It works as intended according to the observable spec. Producer fn should be called on first subscribe call. But it's not clear what is the right way to handle errors in combination with httpLink?

I've dug into source code a little bit and there're methods like map, reduce etc but no one of them accepts an error callback.

Most helpful comment

@valerybugakov take a look at apollo-error-link

Compose this with your httpLink like this:

import { ApolloClient } from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import { createHttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';
import { InMemoryCache } from 'apollo-cache-inmemory';

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

const httpLink = createHttpLink({ ... });

const link = ApolloLink.from([
  ...otherLinksIfNeeded,
  errorLink,
  httpLink,
]);

const client = new ApolloClient({
  link,
  cache: new InMemoryCache(),
  queryDeduplication: true,
});

All 5 comments

@valerybugakov take a look at apollo-error-link

Compose this with your httpLink like this:

import { ApolloClient } from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import { createHttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';
import { InMemoryCache } from 'apollo-cache-inmemory';

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

const httpLink = createHttpLink({ ... });

const link = ApolloLink.from([
  ...otherLinksIfNeeded,
  errorLink,
  httpLink,
]);

const client = new ApolloClient({
  link,
  cache: new InMemoryCache(),
  queryDeduplication: true,
});

@somehandle yep, it's an option. What if I want to handle errors in my custom link? I found the only way to do it is to wrap Observable returned by next(operation) into another Observable.

@valerybugakov what kind of errors do you want to handle? If they are Graphql Errors, you can use .map on the result of forward(operation) since they are returned as a result, if not, you need to subscribe around the other observer. Take a look at the code behind apollo-link-error for some examples!

@jbaxleyiii
What about if I want to catch a network Error?
Lets say a 400, bad request.

Was this page helpful?
0 / 5 - 0 ratings