import { ApolloLink , Observable , Operation , NextLink , FetchResult , ExecutionResult , } from 'apollo-link' ; import { GraphQLError } from 'graphql' ; import { ServerError , ServerParseError } from 'apollo-link-http-common' ; export interface ErrorResponse { graphQLErrors ? : ReadonlyArray < GraphQLError > ; networkError ? : Error | ServerError | ServerParseError ; response ? : ExecutionResult ; operation : Operation ; forward : NextLink ; } export namespace ErrorLink { /**
     * Callback to be triggered when an error occurs within the link stack.
     */ export interface ErrorHandler { ( error ) : Observable < FetchResult > | void ; } } export import ErrorHandler = ErrorLink . ErrorHandler ; export function onError ( errorHandler ) { return new ApolloLink ( ( operation , forward ) => { return new Observable ( observer => { let sub ; let retriedSub ; let retriedResult ; try { sub = forward ( operation ) . subscribe ( { next : result => { if ( result . errors ) { retriedResult = errorHandler ( { graphQLErrors : result . errors , response : result , operation , forward , } ) ; if ( retriedResult ) { retriedSub = retriedResult . subscribe ( { next : observer . next . bind ( observer ) , error : observer . error . bind ( observer ) , complete : observer . complete . bind ( observer ) , } ) ; return ; } } observer . next ( result ) ; } , error : networkError => { retriedResult = errorHandler ( { operation , networkError , graphQLErrors : networkError && networkError . result && networkError . result . errors , forward , } ) ; if ( retriedResult ) { retriedSub = retriedResult . subscribe ( { next : observer . next . bind ( observer ) , error : observer . error . bind ( observer ) , complete : observer . complete . bind ( observer ) , } ) ; return ; } observer . error ( networkError ) ; } , complete : ( ) => { if ( ! retriedResult ) { observer . complete . bind ( observer ) ( ) ; } } , } ) ; } catch ( e ) { errorHandler ( { networkError : e , operation , forward } ) ; observer . error ( e ) ; } return ( ) => { if ( sub ) sub . unsubscribe ( ) ; if ( retriedSub ) sub . unsubscribe ( ) ; } ; } ) ; } ) ; } export class ErrorLink extends ApolloLink { private link : ApolloLink ; constructor ( errorHandler ) { super ( ) ; this . link = onError ( errorHandler ) ; } public request ( operation , forward ) { return this . link . request ( operation , forward ) ; } }