You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5:HttpInterceptor中处理只读HttpErrorResponse获取自定义错误对象

解决Angular中获取自定义JSON错误体的问题

其实你不用纠结HttpErrorResponse是只读的,关键是要在拦截器里用catchError操作符来捕获并转换错误,而不是用do(现在Angular推荐用tap,旧版本也兼容do)来处理。下面是具体的实现方案:

1. 改造你的HttpInterceptor

你需要在拦截器中捕获错误响应,解析出后端返回的自定义JSON错误体,然后把它重新抛出,这样订阅时就能直接拿到这个自定义对象了。

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

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        let customError;
        if (error.error instanceof ErrorEvent) {
          // 处理客户端/网络类错误,返回统一格式的兜底错误
          customError = {
            status: 0,
            url: request.url,
            message: '网络异常或客户端错误'
          };
        } else {
          // 直接取服务器返回的自定义错误体,若后端没返回url则手动补充
          customError = error.error;
          if (!customError.url) {
            customError.url = request.url;
          }
        }
        // 抛出转换后的自定义错误,让订阅的error回调能捕获到
        return throwError(() => customError);
      })
    );
  }
}

2. 在模块中注册拦截器

别忘了把这个拦截器添加到你的AppModule或核心模块的providers数组里,这样它才能生效:

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ErrorInterceptor } from './error.interceptor';

@NgModule({
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: ErrorInterceptor,
      multi: true
    }
  ]
})
export class AppModule { }

3. 在服务的subscribe中获取自定义错误

现在当你在服务里发起请求并订阅时,error回调里就能直接拿到你需要的自定义错误对象了:

this.http.get('/api/abc').subscribe({
  next: (data) => {
    // 处理成功响应逻辑
  },
  error: (customError) => {
    // 这里的customError就是{ status:400, url:"/api/abc", message:"Custom Error Message" }
    console.log('错误状态码:', customError.status);
    console.log('错误信息:', customError.message);
  }
});

关键说明

  • 为什么不用do/tap?因为do/tap只是用来执行副作用操作,不会修改Observable流的内容;而catchError可以捕获错误并返回一个新的Observable,这样就能把自定义错误传递到订阅的error回调里。
  • 区分客户端错误和服务器错误是为了保证异常场景下也能返回统一格式的错误对象,避免订阅时报错。

内容的提问来源于stack exchange,提问作者Ali Kurnaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:40:50