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

如何在Angular中处理500异常错误并实现自定义报错提示

解决方案

核心原因说明

你遇到的两个核心问题根源:

  1. 下载CSV的请求设置了responseType: 'blob',Angular会把所有响应(包括错误响应)统一转为Blob类型,因此后端返回的JSON错误结构被包裹在Blob中,无法直接读取字段
  2. 后端错误是嵌套在errors数组下的结构,和Angular默认把响应体直接挂载到HttpErrorResponse.error的逻辑不匹配,不需要自定义扩展HttpErrorResponse,统一预处理即可

步骤1:在HTTP拦截器中统一预处理错误响应

在拦截器中优先判断错误响应的类型,如果是Blob则先解析为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 ErrorFormatInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      catchError(async (error: HttpErrorResponse) => {
        let processedError = error;
        // 处理Blob类型的错误响应
        if (error.error instanceof Blob) {
          try {
            // 读取Blob内容转为JSON
            const blobText = await error.error.text();
            const errorJson = JSON.parse(blobText);
            // 对齐错误结构,把errors数组第一个元素直接挂载到error属性
            processedError = new HttpErrorResponse({
              error: errorJson.errors?.[0] || error.error,
              headers: error.headers,
              status: error.status,
              statusText: error.statusText,
              url: error.url || undefined
            });
          } catch (e) {
            // 解析失败说明不是JSON格式的错误,走默认逻辑
          }
        } else if (error.error?.errors?.length) {
          // 非Blob场景下直接对齐errors数组结构
          processedError = new HttpErrorResponse({
            ...error,
            error: error.error.errors[0]
          });
        }
        return throwError(() => processedError);
      })
    );
  }
}

记得把拦截器注册到你的AppModule的providers数组中。


步骤2:保留原有错误处理逻辑即可

拦截器已经把错误格式对齐为你预期的结构,原有逻辑不需要修改即可生效:

responseStatus = HttpResponseStatus.INTERNAL_SERVER_ERROR;

// tslint:disable-next-line:variable-name
handleError(_request: HttpRequest<any>, response: HttpErrorResponse): void {
  if (response.status === this.responseStatus) {
    if (response.error?.type === 'BWPErpIntegrationBapiError') {
      this.globalMessageService.add(
        response.error?.message,
        GlobalMessageType.MSG_TYPE_ERROR
      );
    } else {
      this.globalMessageService.add(
        { key: 'httpHandlers.internalServerError' },
        GlobalMessageType.MSG_TYPE_ERROR
      );
    }
  }
}

内容的提问来源于stack exchange,提问作者Torjescu Sergiu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 00:30:01