Angular 5 HttpInterceptor错误处理:优先触发调用方错误处理器
实现服务自定义错误处理器优先于全局HttpInterceptor的方案
这个需求其实很常见,咱们可以通过给请求添加专属标记的方式,让全局Interceptor能识别出哪些请求要跳过自身的错误处理,直接交给发起请求的服务来处理。下面一步步来实现:
1. 定义一个「跳过全局错误处理」的标记
我们用Angular的HttpContext(Angular 14+支持,更干净不会和业务头冲突)来创建一个全局token,用来标记请求是否需要跳过全局错误处理:
// skip-global-error-handling.token.ts import { HttpContextToken } from '@angular/common/http'; // 默认值为false,即不跳过全局处理 export const SKIP_GLOBAL_ERROR_HANDLING = new HttpContextToken<boolean>(() => false);
如果你的项目是Angular 14以下的版本,可以改用自定义HTTP头的方式,比如设置X-Skip-Global-Error: true,后面的逻辑对应检查请求头即可。
2. 修改全局ErrorHttpInterceptor的逻辑
在Interceptor的catch块里,先检查请求是否携带了「跳过全局处理」的标记,如果有就直接把错误重新抛出,交给服务自己处理;没有的话再走全局错误处理逻辑:
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpInterceptor, HttpErrorResponse, HttpContext } from '@angular/common/http'; import { catchError } from 'rxjs/operators'; import { throwError } from 'rxjs'; import { SKIP_GLOBAL_ERROR_HANDLING } from './skip-global-error-handling.token'; import { NotificationService } from './notification.service'; @Injectable() export class ErrorHttpInterceptor implements HttpInterceptor { constructor(private notificationService: NotificationService) {} intercept(request: HttpRequest<unknown>, next: HttpHandler) { return next.handle(request).pipe( catchError((error: HttpErrorResponse) => { // 从请求上下文获取标记 const skipGlobalHandling = request.context.get(SKIP_GLOBAL_ERROR_HANDLING); if (skipGlobalHandling) { // 重新抛出错误,让发起请求的服务自行处理 return throwError(() => error); } // 全局错误处理逻辑,比如弹出通知、记录日志等 this.notificationService.showError(`请求失败: ${error.message}`); // 可以根据需求选择重新抛出错误或者返回默认值 return throwError(() => error); }) ); } }
3. 在需要自定义错误处理的服务中使用标记
当服务需要自己处理错误时,发起请求时带上这个「跳过全局处理」的标记,然后通过catchError实现自己的错误逻辑:
import { Injectable } from '@angular/core'; import { HttpClient, HttpContext } from '@angular/common/http'; import { catchError } from 'rxjs/operators'; import { throwError } from 'rxjs'; import { SKIP_GLOBAL_ERROR_HANDLING } from './skip-global-error-handling.token'; @Injectable() export class CustomDataService { constructor(private http: HttpClient) {} fetchCustomData() { return this.http.get('/api/custom-data', { // 添加上下文标记,告知全局Interceptor跳过处理 context: new HttpContext().set(SKIP_GLOBAL_ERROR_HANDLING, true) }).pipe( catchError((error: HttpErrorResponse) => { // 服务专属的错误处理逻辑,比如自定义提示、特殊降级处理 console.error('服务内部处理错误:', error); return throwError(() => new Error('自定义服务错误提示')); }) ); } }
4. 普通服务无需额外配置
对于不需要自定义错误处理的服务,正常发起请求即可,全局Interceptor会自动接管错误处理:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable() export class RegularDataService { constructor(private http: HttpClient) {} fetchRegularData() { // 没有标记,全局Interceptor会处理错误 return this.http.get('/api/regular-data'); } }
这样就完美实现了「服务自定义错误处理优先,全局处理兜底」的需求啦~
内容的提问来源于stack exchange,提问作者Nani
相关产品推荐
相关产品推荐

