Angular错误处理:利用拦截器实现模态框统一报错
用Angular 5 Interceptor实现集中式错误处理并触发模态框
没问题,咱们可以通过全局错误服务+HTTP拦截器的组合来实现你的需求,既统一处理所有HTTP请求错误,又能触发组件里的模态框。下面是一步步的实现方案:
1. 创建全局错误服务(ErrorService)
这个服务用来在拦截器和组件之间传递错误信息,用BehaviorSubject实现跨组件通信,确保组件能实时收到错误通知:
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @Injectable() export class ErrorService { private errorSubject = new BehaviorSubject<any>(null); public error$ = this.errorSubject.asObservable(); // 发送错误信息到订阅者 sendError(error: any) { this.errorSubject.next(error); } // 清空错误状态(可选,比如关闭模态框后调用) clearError() { this.errorSubject.next(null); } }
记得在AppModule的providers数组里注册这个服务,让它成为全局可用的实例。
2. 创建HTTP错误拦截器
拦截所有HTTP请求的错误,把格式化后的错误信息传给ErrorService:
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/catch'; import { ErrorService } from './error.service'; @Injectable() export class ErrorInterceptor implements HttpInterceptor { constructor(private errorService: ErrorService) {} intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(request) .catch((error: HttpErrorResponse) => { // 格式化错误信息,和你原来的handleError逻辑对齐 let errorMessage: string; if (error.error instanceof ErrorEvent) { // 客户端/网络层面的错误 errorMessage = error.error.message; } else { // 服务器返回的错误 if (error.text()) { errorMessage = error.text(); } else { errorMessage = error.status === 401 ? 'You are not authorised to get this resource' : error.message; } } // 把错误发送给ErrorService,通知组件展示模态框 this.errorService.sendError({ errorMessage: errorMessage, errorStatus: error.status }); // 可选:继续抛出错误,方便其他特殊场景处理 return Observable.throw(error); }); } }
接着在AppModule里注册拦截器:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { ErrorInterceptor } from './error.interceptor'; @NgModule({ ... providers: [ ... { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true, deps: [ErrorService] } ] }) export class AppModule { }
3. 修改你的VerificationComponent
现在不用在每个subscribe里写错误回调了,直接订阅ErrorService的错误事件来触发模态框:
import { Component, OnInit, ViewChild } from '@angular/core'; import { ModalComponent } from './modal.component'; import { MyService } from './my.service'; import { ErrorService } from './error.service'; export class VerificationComponent implements OnInit { @ViewChild('modalError') displayErrorRef: ModalComponent; errorMesage = ""; loadCandidate: ICandidate; userName: string; constructor( private _myService: MyService, private _appService: AppService, // 保留你原来的appService private _errorService: ErrorService ) {} ngOnInit() { // 订阅错误服务的事件,收到错误就展示模态框 this._errorService.error$.subscribe(error => { if (error) { this.errorMesage = error.errorMessage; this.displayErrorRef.show(); } }); } getNextRecord() { this.errorMesage = ""; this._myService.getCandidate() .subscribe(candidate => { this.loadCandidate = candidate; this.userName = this._appService.getUser(); // 这里再也不用写error回调啦! }); } hideModalError() { this.displayErrorRef.hide(); this._errorService.clearError(); // 清空错误状态,避免重复触发 } tryGetNextRecord() { this.hideModalError(); this.getNextRecord(); } }
4. 简化MyService
去掉原来的handleError方法和catch操作符,因为拦截器会统一处理所有HTTP错误:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import { ICandidate } from './candidate.model'; @Injectable() export class MyService { private _getCandidateUrl = 'your-api-url-here'; constructor(private _http: HttpClient) {} getCandidate(): Observable<ICandidate> { return this._http.get(this._getCandidateUrl, this.jwt()) .map((response: any) => <ICandidate>response.json()); // 删除原来的.catch(this.handleError) } // 保留你的jwt请求头方法 private jwt() { // 你的joken逻辑 } }
方案优势
- 集中管理错误:所有HTTP请求的错误都在拦截器里统一处理,不用在每个服务/组件里重复写错误逻辑;
- 组件与拦截器解耦:通过
ErrorService做中间层,拦截器不用直接依赖组件,符合Angular的依赖注入设计原则; - 扩展性强:如果其他组件也需要错误提示,只需要订阅
ErrorService的error$事件即可。
内容的提问来源于stack exchange,提问作者D.B
相关产品推荐
相关产品推荐

