2

I am working on Angular 8

I am trying to centralise error handling through Interceptor

My Interceptor code is running , but it is not returning any error

import {
    HttpEvent,
    HttpInterceptor,
    HttpHandler,
    HttpRequest,
    HttpResponse,
    HttpErrorResponse
   } from '@angular/common/http';
   import { Observable, throwError } from 'rxjs';
   import { retry, catchError } from 'rxjs/operators';
import { RestService } from './restservice';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';


@Injectable()
   export class HttpErrorInterceptor implements HttpInterceptor {

    constructor(private rest : RestService , private route : Router){}



    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      // console.log('jcsjdsjd');
      // console.error('xjxfjb');
      // console.log(request);
      // console.log(next);
      return next.handle(request).pipe(catchError(err => {
        console.log(err);
          if (err.status === 401) {
              // auto logout if 401 response returned from api
              // this.authenticationService.logout();
              location.reload(true);
          }

          const error = err.error.message || err.statusText;
          return throwError(error);
      }))
  }
} 

I have also defined interceptor in Providers of app.module.ts

  providers: [RestService  , AuthGuard ,   commonRest    ,  {
    provide: HTTP_INTERCEPTORS,
    useClass: HttpErrorInterceptor,
    multi: true
  }],

response that I am getting on request with error 403 is :

    {
  "messagecode": 403,
  "message": "not valid token!"
}
7
  • have you tried using tap() method and check if (err instanceof HttpErrorResponse) ? Commented Jan 17, 2020 at 13:34
  • @BrianDucca can you share a dummy code for using tap() Commented Jan 17, 2020 at 13:37
  • of course: return next.handle(request).pipe( tap(() => {},(err: any) => { if (err instanceof HttpErrorResponse) { if (err.status === 401) { //do your thing } } })); and also add import import {tap} from 'rxjs/operators'; Commented Jan 17, 2020 at 13:40
  • @BrianDucca I tryed with you code ->>>> intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { console.log(request); console.log(next); return next.handle(request).pipe( tap(() => {},(err: any) => { console.log(err); if (err instanceof HttpErrorResponse) { console.log(err); if (err.status === 401) { console.log("It's 401"); } } })); } >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> But console inside next.handle(request) is not returning anything on error 403 Commented Jan 17, 2020 at 13:46
  • Maybe the problem is how do you return your error in your api?, in my case, that code works perfect, i have an spring-boot API (Java) & Angular 8 frontend app. What is your api made of? Commented Jan 17, 2020 at 13:57

2 Answers 2

1

For use interceptor globally and the providers are in core module should add @Injectable({ providedIn: 'root' }) in the top of interceptors like here https://stackblitz.com/edit/angular-http-interceptor-working-for-lazy-loaded-module?file=src/app/core/token-interceptor.service.ts

Sign up to request clarification or add additional context in comments.

3 Comments

I'm not sure that by using providedIn: 'root' you can provide 'global' interceptors. Interceptors should be provided with the HTTP_INTERCEPTORS token. Here's why: github.com/angular/angular/blob/master/packages/common/http/src/…
when you work with lazy modules its the only way I make it works. you can see in the example that I use HTTP_INTERCEPTORS in core modules
I did notice that. But I can’t understand why you also added “providedIn”. I might be missing something
0

Make sure your API returns JSON response in the following format,

{
   "status" : "403",
   "message" : "Session expired"
}

The following work for me, (I am having tap in the example below, in case if you want to extract something from a successful JSON response).

The errors can be handled in the catchError section. See, provided error.status examples for 403 & 401. Feel free to customise that section.

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

    return next.handle(request).pipe(
      tap(evt => {
        if (evt instanceof HttpResponse) {
          
        }
      }),
      catchError(err => {
        if (err.status === 403) {
          // Handle 403 specific errors
        } else if (err.status === 401) { 
          // Handle 401 specific errors
        }

        const error = err.error.message || err.statusText;
        return throwError(error);
      }), map(event => {
        if (event instanceof HttpResponse) {

        }
        return event;
      }), catchError(this.handleError));
  }

  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      // console.error(
      //   `Backend returned code ${error.status}, ` +
      //   `body was: ${error.error}`);

      // TODO :  do the logout here.
      // console.log(
      //   `Backend returned code ${error.status}, ` +
      //   `body was: ${error.error}`);
      // this.router.navigate(['/login'], { queryParams: { returnUrl: '' }});
    }
    // return an observable with a user-facing error message
    return throwError(error);

  }

I hope this helps someone.

Thanks.

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.