【问题标题】:Best way to handle HTTPErrorResponse with Angular 7使用 Angular 7 处理 HTTPErrorResponse 的最佳方法
【发布时间】:2020-01-08 04:25:05
【问题描述】:

所以当前端有错误请求时,后端Server返回不同的状态码和HttpErrorResponse;我已经意识到管理这个问题的最佳方法是在 Ionic 4/Angular 7 设置中使用拦截器。

我已经尝试过几次拦截器,但遇到了不同的问题。我现在正在按照link 中的步骤进行操作

我的服务是这样定义的:

     saveLocationNew(request: AddLocationRequest, entityId:string, userId:string): Observable<AddLocationResponse> {

          return this.httpClient.post<AddLocationResponse>(this.addLocationUrl, request ,  {headers:Constants.getHeaders(userId,entityId)})
       }

现在有了拦截器:

    saveLocationNew(request: AddLocationRequest, entityId:string, userId:string): Observable<AddLocationResponse> {

      return this.httpClient.post<AddLocationResponse>(this.addLocationUrl, request ,  {headers:Constants.getHeaders(userId,entityId)})
      .pipe(
    tap(_ => console.log('creating a new location')),
    catchError(this.handleError('new Location',[]))
  );  
}

问题是我现有的服务返回了 AddLocationResponse 类型的响应;但是如果出现错误,我如何定义返回对象的类型,离子服务也会抛出这个错误:

    ERROR in src/app/services/location.service.ts(42,11): error TS2322: Type 'Observable<any[] | AddLocationResponse>' is not assignable to type 'Observable<AddLocationResponse>'.
[ng]   Type 'any[] | AddLocationResponse' is not assignable to type 'AddLocationResponse'.
[ng]     Type 'any[]' is not assignable to type 'AddLocationResponse'.
[ng]       Property 'name' is missing in type 'any[]'.
[ng] src/app/services/location.service.ts(74,49): error TS2339: Property 'message' does not exist on type 'T'.

知道实现拦截器的最佳方法是什么,这样组件(*.page.ts 文件)就不需要任何更改。

我的拦截器看起来像这样:

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

  const token = localStorage.getItem('token');

  if (token) {
    request = request.clone({
      setHeaders: {
        'Authorization': token
      }
    });
  }

  if (!request.headers.has('Content-Type')) {
    request = request.clone({
      setHeaders: {
        'content-type': 'application/json'
      }
    });
  }

  request = request.clone({
    headers: request.headers.set('Accept', 'application/json')
  });

  return next.handle(request).pipe(
    map((event: HttpEvent<any>) => {
      if (event instanceof HttpResponse) {
        console.log('event--->>>', event);
      }
      return event;
    }),
    catchError((error: HttpErrorResponse) => {
      if (error.status === 401) {
        if (error.error.success === false) {
          this.presentToast('Login failed');
        } else {
            console.log(' route this to right place');
        //   this.router.navigate(['auth/login']);
        }
      }
          if (error.status === 500) {
        if (error.error.success === false) {
          this.presentToast('Something went wrong, Please contact Administrator');
        } else {
            console.log(' route this to right place');
        //   this.router.navigate(['auth/login']);
        }
      }
      //431

       if (error.status === 431) {
        if (error.error.success === false) {
          this.presentToast('Something went wrong with the HttpRequest, Please contact Administrator');
        } else {
            console.log(' route this to right place');
        //   this.router.navigate(['auth/login']);
        }
      }

      // add all the other error codes here 
      return throwError(error);
    }));
}

我不确定还需要添加/修改什么,以便拦截 HttpErrorResponse。

【问题讨论】:

  • 你使用了错误的拦截器。您应该使用拦截器来捕获所有或大部分请求的错误,所有这些都来自一个地方。
  • @Dino 进行了更改,但代码 431 和 500 出现错误我可以看到它们仍未被拦截器处理

标签: angular angular7 ionic4 angular-http-interceptors


【解决方案1】:

你可以这样使用它

    saveLocationNew(request: AddLocationRequest, entityId:string, userId:string): Observable<AddLocationResponse> {

      return this.httpClient.post<AddLocationResponse>(this.addLocationUrl, request ,  {headers:Constants.getHeaders(userId,entityId)})
      .pipe(
    tap(_ => console.log('creating a new location')),
    catchError(this.handleError<string>('stats')))
  )
}

现在创建一个名为handle error的函数来处理所有这样的错误请求

private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(error);   
      console.log(`${operation} failed: ${error.message}`);
      if(error.error.message == "Token is invalid!"){
        localStorage.removeItem('token');
        this.router.navigateByUrl('/login');
      }
      else{
        return throwError(error)
      }
      return of(result as T);
    };
  }

如果您想在组件中处理该错误,则需要抛出该错误。希望这会对你有所帮助。

【讨论】:

  • 嘿@Ankit 这将是旧的 Ionic 版本;特别是3;但在 ionic 4 中,我们有拦截器
【解决方案2】:

我从源代码中删除了 HttpClientModule 的多个定义,并且能够让一切正常工作。

【讨论】:

    猜你喜欢
    • 2016-03-02
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    相关资源
    最近更新 更多