Search code examples
angularrxjsrefresh-token

Stop a pipe in the middle


In my angular app, I have a token refresh interceptor which intercepts 401-Unauthorized errors, attempts to refresh an access token, and perform the original http request again.

The token refresh endpoint may also fail in some cases, and return a known error (in my case it's a 400 invalid_grant error).

The part of the interceptor that refreshes the token:

 return this.httpClient
  .request('POST', "token", { observe: 'response' })
  .pipe(
    map(response => {
      // some logic when the token was refreshed successfully
    }),
    catchError(err => {
      this.routingService.navigateToLoginNoQuery();
      return throwError(err); // a 400 - invalid_grant error
    })
  );

When this happens, it gets to a catchError operator, that does 2 things: logout (with redirection to the login page), and returns throwError(error), this error it throws is the 400-Invalid_grant error.

This causes the new error to arrive to some catchError operators in the functions that originally triggered the refresh token.

Just for context: I log the errors in the catch blocks, and I want to avoid logging these kind of errors, because they usually only mean that the user's token is expired.

What I would like to do is to somehow stop this operators chain, and just redirect to the login page.

Is that possible to stop a pipe in the middle, and avoid both getting to an outer catchError and to the next operator in the pipe?


Solution

  • You could return an empty Observable to prevent events or errors from reaching a component that is going to be destroyed:

    return this.httpClient
      .request('POST', "token", { observe: 'response' })
      .pipe(
        map(response => {
          // some logic when the token was refreshed successfully
        }),
        catchError(err => {
          this.routingService.navigateToLoginNoQuery();
          return EMPTY;
        })
      );