如何在Angular中处理500异常错误并实现自定义报错提示
解决方案
核心原因说明
你遇到的两个核心问题根源:
- 下载CSV的请求设置了
responseType: 'blob',Angular会把所有响应(包括错误响应)统一转为Blob类型,因此后端返回的JSON错误结构被包裹在Blob中,无法直接读取字段 - 后端错误是嵌套在
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
相关产品推荐
相关产品推荐

