http 错误拦截器不起作用 CatchError 不适用于 Angular 13

Ljt*_*Ljt 3 rxjs typescript angular

这是我的错误拦截器类。我需要向 cComponent 类可观察方法抛出错误错误:我已经检查过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');                        
                      }
Run Code Online (Sandbox Code Playgroud)

else if ([400].includes(error.status) && error.error?.Message === '会话已过期') {

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

}
Run Code Online (Sandbox Code Playgroud)

成分

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

  }
Run Code Online (Sandbox Code Playgroud)

服务

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;
                          })
                );
   }
Run Code Online (Sandbox Code Playgroud)

我需要在拦截器类中抛出错误。我从服务器收到 400 错误。我需要显示来自拦截器类的错误消息,并且需要将错误抛出到控制器方法。

编辑:

错误调试

在此输入图像描述

编辑:调试后发现它的发生是因为

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

我需要在此方法中进行更新吗?

rfp*_*rod 6

如果您想将错误传递给组件,并且不想使用状态管理在类之间共享错误响应,请尝试在拦截器中点击它,例如

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

Run Code Online (Sandbox Code Playgroud)

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

Run Code Online (Sandbox Code Playgroud)
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();
        }
      )
    );
  }
}

Run Code Online (Sandbox Code Playgroud)
<!-- the component template -->

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

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

Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在这里观看直播:

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();
    }
Run Code Online (Sandbox Code Playgroud)