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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:37:46