Unauthorized intercepter for Angular

In his article on Medium, Ryan Chenkie suggests using the following code to intercept 401 responses:

import 'rxjs/add/operator/do';

export class JwtInterceptor implements HttpInterceptor {

    constructor(public auth: AuthService) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<httpevent<any>> {
    
        return next.handle(request).do((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // do stuff with response if you want
            }
        }, (err: any) => {
            if (err instanceof HttpErrorResponse) {
                if (err.status === 401) {
                    // redirect to the login route
                    // or show a modal
                }
            }
        });
    }
}

There is a problem with this approach, and it is the use of the Rx operator do(). The observable chain will continue after the error handler in the second argument of do(). The error response may bubble to a generic error handler or to a service or component.

In our case this prevented a redirect to the login page.

I suggest the following improvement, replacing do() with catch():

import 'rxjs/add/operator/catch';

@Injectable()
export class UnauthorizedInterceptor implements HttpInterceptor {
    constructor(
        private router: Router
    ) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).catch((err: any) => {
            if (err instanceof HttpErrorResponse && err.status === 401) {
                this.router.navigate(['/login'], {
                    queryParams: {
                        redirectTo: document.location.pathname
                    }
                });

                // this response is handled
                // stop the chain of handlers by returning empty
                return Observable.empty();
            }

            // rethrow so other error handlers may pick this up
            return Observable.throw(err);
        });
    }
}

Author:  | 01 okt 2017

 

Share This