3

I am using Angular 7 and I have used HTTP Interceptor in my application.

I am not able to track 401 status code in that HTTP Interceptor.

I tried pitting catchError and tap but it gives status 0, I want 401.

My code is here:

return next.handle(request).pipe(tap(event => {
            console.log('the ev is :', event);
            if (event instanceof HttpResponse) {
                this.onEnd();
            }
         }, err => {
            if (err instanceof HttpErrorResponse) {
                console.log('the eeeeeee is :', err);
                this.onEnd();
                // User logged out
                if (err.status === 401) {
                    this.router.navigate(['logout']);
                }
            }
        })).pipe(catchError(error => {
            console.log('the ee is :', error);
            return Observable.throw(error);
        }));

Thanks.

3
  • I'm not so sure sure the tap is hit when there's an error. Google for it. Commented Mar 27, 2019 at 7:17
  • i face this issue and reason was only in developement mode i was getting status 0 while in service i was getting 401 while in interceptor i was getting 0. when i deploy the application on the server. everything was working fine and i got correct statuses without any change in code or in configuration. i dont know why but it was happening only in development mode. Commented Mar 27, 2019 at 7:48
  • @FarhatZaman, Even after deploying the app on the server the same issue exists. Commented Mar 27, 2019 at 11:59

4 Answers 4

6

You have an error handler in the tap method and then a separately piped catchError. Unless you intend to act on the received response i.e http 200. A simple interceptor implementation would be:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

  return next.handle(request).pipe(
      catchError(err => {
        if (err instanceof HttpErrorResponse) {

          if (err.status === 401 || err.status === 403) {
              // Invalidate user session and redirect to login/home
          }

          // return the error back to the caller
          return throwError(err);
        }
      }),
      finalize(() => {
        // any cleanup or final activities
      })
    );
}
Sign up to request clarification or add additional context in comments.

Comments

4

I'm using angular 6 and this redirects to the login page when there's an error 401 or 403. I think it should work in angular 7. There should be other ways to do it but I share what works for me in this case. Hope it helps.

intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
      catchError(
        err =>
          new Observable<HttpEvent<any>>(observer => {
            if (err instanceof HttpErrorResponse) {
              const errResp = <HttpErrorResponse>err;
              if (errResp.status === UNAUTHORIZED || err.status === FORBIDDEN) {
                this.authService.goToLogin(this.router.url);
              }
            }
            observer.error(err);
            observer.complete();
          })
      )
    );

}

Maybe someone can suggest me what's the better way to carry out this kind of stuff.

3 Comments

There is no need to create a new Observable in the error handler and call observer.error(err) again. You can simply return the err which will continue the observable with error to the actual caller. I have posted a sample example below.
@dcg Still getting 0 in errResp.status.
@ArpitMeena Are you sure you're hitting the server?
1
import { Injectable } from '@angular/core'
import { HttpEvent, HttpRequest, HttpHandler, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'
import { Router } from '@angular/router'
import { Observable, of } from 'rxjs'
import { catchError } from 'rxjs/operators'

@Injectable()
export class ServerErrorInterceptor implements HttpInterceptor {
  constructor(public router: Router) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error: any) => {
        if (error.status == 401 || error.status == 0) {
          this.router.navigate(['/'])
        } else {
        }
        return of(error)
      }),
    )
  }
}
providers: [
  {
    provide: HTTP_INTERCEPTORS,
    useClass: ServerErrorInterceptor,
    multi: true
  }
]

Comments

1

Try this

@Injectable()
export class HTTPListener implements HttpInterceptor {
  constructor(private status: HTTPStatus) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      map(event => {
        return event
      }),
      catchError(err => {
        if (err.status === 401) {
        }

        const error = err.error.message || err.statusText
        return throwError(error)
      }),
      finalize(() => {}),
    )
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.