【问题标题】:http error interceptor not working CatchError not working with angular 13http错误拦截器不起作用CatchError不适用于角度13
【发布时间】:2022-01-15 23:47:11
【问题描述】:

这是我的错误拦截器类。我需要向 ccomponent 类 observable 方法抛出错误错误: 我检查过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
              })
          )
  }

}

组件

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

  }

服务

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

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

编辑:

错误调试

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

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

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

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

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

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

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

    在这里观看直播:

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

    【讨论】:

    • 谢谢 .actullay 我正在使用从组件调用服务方法..在我的情况下我必须改变什么?
    • @Ajt 请再次检查我的答案,我已经更新了。请参阅我评论末尾的附言。
    • 其实在以前的版本中它工作得很好..没有tap方法的任何其他选项意味着使用catchError
    • @Ajt 我不这么认为。当你使用 catchError 并在其中返回一个新错误,或者返回捕获的错误的 observable 时,它​​会循环。当你使用 catchError 操作符时,你告诉你的代码停止处理一个错误的 observable。因此,只有在您想停止处理错误时才应该使用 catchError。
    • 是否可以使用 this.router.navigate(['404']);在水龙头内
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多