Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

http error interceptor not working CatchError not working with angular 13

This is my error interceptor class. I need to throw error error to ccomponent class observable method: i haved checked throwError(error) is now deprecated, but there is no new Error(HttpErrorResponse)

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
    constructor(private toastr: ToastrService,private authService: AuthService,
        private router:Router) {
    }

    intercept( request: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> {
      return next.handle(request)
          .pipe(
              catchError((error: HttpErrorResponse) => {

                debugger
                  let message = '';
                  if (error.error instanceof ErrorEvent) {
                      // handle client-side error
                      message = `Error: ${error.error.message}`;
                      this.toastr.error(message);
                  } else {
                      // handle server-side error
                      debugger
                    
                      message = `Error: ${ error?.error?.Message || error?.statusText}`; 
                      if(!error.status)
                      {
                          this.toastr.error('Not able connect to server');                        
                      }

else if ([400].includes(error.status) && error.error?.Message === 'Session Expired') {

                     this.toastr.error("Session Expired");
                      this.authService.logout();
                     
                  }
                     .....

                    else if ([404].includes(error.status)) {
                      
                          this.router.navigate(['404']);  
                    }  
                   
                    else
                    {                  
                        this.toastr.error(message); 
                    } 
                  }
                 
                 return throwError(() => error) //If i throw errror like this it is coming error inteceptor agian
              })
          )
  }

}

component

getEditCollectionById(id:string)
  {
     debugger
     this.collectionService.getEditCollectionById(id).pipe(takeUntil(this.unsubscribe$)).subscribe({
       next: (result: any)  => {            
         if (result) {          
          
            this.collection=result;

         }
         else {
            this.close();
         }
       },
       error: (error:any) => {
           // If i throw error in interceptor it is not coming here
          this.goToDetail(this.collectionId);
       }
     });   

  }

service

getEditCollectionById(id: string): Observable<ICollection> {
          
      return  this.httpClient.get<Result<ICollection>>(baseUrl + '/Collection/GetEditCollectionById'+ `/${id}`) 
                  .pipe(map((res:any)=>{  res.data.valueDate = new Date(res.data.valueDate);       
                             return res.data;
                          })
                );
   }

i need to throw error in interceptor class. i am getting 400 error from server. i need show error message from interceptor class and i need to throw error to controller method.

EDIT:

Error Debug

enter image description here

EDIT: afer debugging infigured out its happening becuase of

 logout()  {
        
        debugger
        this.httpClient.post<any>(`${baseUrl}/Auth/revoke-token`, {}, { withCredentials: true })
        .subscribe(); 
             
        this.stopRefreshTokenTimer();
        this.setUserValue(null);
       this.router.navigate(['login']);
    }

Is there an update i need to do in this method?

like image 246
Ajt Avatar asked Sep 16 '26 14:09

Ajt


2 Answers

If you want to pass an error to the component, and don't want to use state management to share an error response between classes, try tapping it in the interceptor like

import {
  HttpErrorResponse,
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
  intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      tap({
        next: () => null,
        error: (error: HttpErrorResponse) => {
          console.log(
            'the interceptor has caught an error, process it here',
            error
          );
        },
      })
    );
  }
}

another option is to use throwError

import {
  HttpErrorResponse,
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
  intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        console.warn(
          'the interceptor has caught an error, process it here',
          error
        );
        return throwError(() => error);
      })
    );
  }
}

import { HttpClient, HttpErrorResponse, HttpEvent } from '@angular/common/http';
import { Component, VERSION } from '@angular/core';
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  public name = 'Angular ' + VERSION.major;

  public error?: HttpErrorResponse;

  constructor(private readonly http: HttpClient) {
    this.getData().subscribe();
  }

  public getData() {
    return this.http.get('xxx').pipe(
      catchError(
        (error: HttpErrorResponse, caught: Observable<HttpEvent<unknown>>) => {
          console.error(
            'the component has caught an error, process it here',
            error
          );
          this.error = error;
          return of();
        }
      )
    );
  }
}

<!-- the component template -->

<hello name="{{ name }}"></hello>
<div>Caught error: {{ error?.message }}</div>

<p>Start editing to see some magic happen :)</p>

enter image description here

see live here:

  • https://stackblitz.com/edit/angular-ivy-vmnh7p
  • https://stackblitz.com/edit/angular-ivy-kcqcjf

PS: how to handle error in the logout method

logout()  {
        this.httpClient.post<any>(`${baseUrl}/Auth/revoke-token`, {}, { withCredentials: true })
        .pipe(catchError(error => {
          // do something with the error here
          return of();
        }),
        tap(() => {
          this.stopRefreshTokenTimer();
          this.setUserValue(null);
          this.router.navigate(['login']);
        }))
        .subscribe();
    }
like image 153
rfprod Avatar answered Sep 18 '26 05:09

rfprod


Check on this sample code

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { tap } from 'rxjs/operators';
import { AccountService } from '../services/account.service';
import { AlertService } from '../services/alert.service';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(private accountService: AccountService, private alertService: AlertService) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            tap({
                next: () => null,
                error: (err: HttpErrorResponse) => {
                    if ([401, 403].includes(err.status) && this.accountService.signInResponse)
                        this.accountService.signOut(); // auto logout if 401 or 403 response returned from api

                    const error = err.error?.message || err.status;
                    this.alertService.error(error);
                    return throwError(error);
                },
            })
        );
    }
}
like image 44
Bercove Avatar answered Sep 18 '26 04:09

Bercove



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!