简体   繁体   English

http 错误拦截器不工作 CatchError 不工作 angular 13

[英]http error interceptor not working CatchError not working with angular 13

This is my error interceptor class.这是我的错误拦截器 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)我需要向 ccomponent class 可观察方法抛出错误错误:我已经检查过throwError(error) 现在已弃用,但没有新的 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') { 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.我需要在拦截器 class 中抛出错误。 i am getting 400 error from server.我从服务器收到 400 错误。 i need show error message from interceptor class and i need to throw error to controller method.我需要显示来自拦截器 class 的错误消息,我需要向 controller 方法抛出错误。

EDIT:编辑:

Error Debug错误调试

在此处输入图像描述

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?我需要在这种方法中进行更新吗?

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如果您想将错误传递给组件,并且不想使用 state 管理在类之间共享错误响应,请尝试在拦截器中点击它,例如

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另一种选择是使用 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>

在此处输入图像描述

see live here:在这里看直播:

PS: how to handle error in the logout method PS:注销方法报错如何处理

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();
    }

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);
                },
            })
        );
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM