apollographql/apollo-link

ApolloLink emits both value and error in catch

Open

#542 opened on Mar 10, 2018

View on GitHub
 (1 comment) (0 reactions) (0 assignees)TypeScript (335 forks)auto 404
blockinggood first issuehas-reproduction

Repository metrics

Stars
 (1,427 stars)
PR merge metrics
 (PR metrics pending)

Description

Expected Behavior

Observable.catch should emit either recovered value or error.

Actual Behavior

The error is emitted and bubbled up the Rx Observable chain just fine. When caught by the subscriber error action, the observable will be closed and the value emition is never handled causing the app to crash.

A simple reproduction

Place any query and ensure a response with HTTP status code set to anything above 300. Make sure the errors is set and not null.

See demo project here

Issue Labels

  • has-reproduction
  • feature
  • blocking
  • good first issue

Some details:

I believe the issue is in: https://github.com/apollographql/apollo-link/blob/c9843e5a051acbc5e1760d5f9a800bdc369f1e8f/packages/apollo-link-http/src/httpLink.ts#L130

        ...
        .catch(err => {
          if (err.name === 'AbortError') return;
          if (err.result && err.result.errors && err.result.data) {
            observer.next(err.result);
          } 
          observer.error(err);
        });

The above observer.next() ends-up in Promise.reject() in ApolloClient QueryManager.fetchRequest(). The rejection of the Promise will cause the involving Observable stream to be completed.

The above code when modified to the sample below fixes the experienced issues:

        ...
        .catch(err => {
          if (err.name === 'AbortError') return;
          if (err.result && err.result.errors && err.result.data) { // Recover from error and emit value
            observer.next(err.result);
          }  else { // Or just emit error and close stream
            observer.error(err);
          }
        });

Edit by @evans: Attempt to get Apollo Bot to run

Contributor guide