Apollo 11: Error Handling & Links
easy⏱ 5 mincourseapollo
ApolloLink chain
An Apollo Link is middleware for your GraphQL operations. Links form a chain — each link can inspect, modify, or short-circuit the operation before passing it to the next link. Common links:
- HttpLink: The terminating link that sends operations to your server.
- ErrorLink (via
onError): Catches GraphQL and network errors.
- RetryLink: Automatically retries failed operations.
- ApolloLink.split: Routes operations to different links based on a condition (e.g., subscriptions via WebSocket, queries via HTTP).
import { ApolloClient, InMemoryCache, HttpLink, ApolloLink, from } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.forEach(({ message, locations, path }) => {
console.error(`[GraphQL error]: ${message}`);
});
}
if (networkError) {
console.error(`[Network error]: ${networkError}`);
}
});
const retryLink = new RetryLink({
delay: { initial: 300, max: 3000, jitter: true },
attempts: { max: 3, retryIf: (error) => !!error },
});
const httpLink = new HttpLink({ uri: '/graphql' });
const client = new ApolloClient({
link: from([errorLink, retryLink, httpLink]),
cache: new InMemoryCache(),
});
Build an error handling chain
Create an Apollo Client with a link chain using from([...]). Add an onError link that logs GraphQL errors and network errors to the console. Add a RetryLink that retries up to 3 times with exponential backoff. Use ApolloLink.split to route subscription operations to a WebSocketLink and everything else to HttpLink.
errorPolicy variants
The errorPolicy option on useQuery/useMutation controls how errors are surfaced:
- none (default): Errors in the
error field, data is undefined.
- ignore: Errors are discarded, only valid data is returned.
- all: Both
data and error can coexist — partial data with errors.
Use all when you want to show whatever data came back even if some fields errored (common with federated schemas).
const { data, error } = useQuery(GET_DASHBOARD, {
errorPolicy: 'all',
});
// data AND error can both have values
Error Boundaries with Apollo
Combine React Error Boundaries with Apollo's error handling for a robust strategy: onError link handles global logging/auth redirects, errorPolicy: 'all' surfaces partial data, and React Error Boundaries catch any unhandled rendering errors. For mutations, always handle errors in the .catch() or mutation result — don't rely on Error Boundaries for user-initiated actions.