CustomErrorHandler 未捕获 Angular 18 新构建系统中的异常

问题描述 投票:0回答:1

我的 Angular 18 应用程序中有一个自定义错误处理程序,该处理程序应该捕获从后端 (ASP.NET) 抛出的未处理的异常。该实现在 Angular 18 浏览器构建系统中运行良好,但在新的 Angular 18 构建系统中无法捕获异常。

这是我的 CustomErrorHandler 的简化版本:

import { ErrorHandler, Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable()
export class CustomErrorHandler implements ErrorHandler {
  private onUnhandledException = new Subject();
  onUnhandledException$ = this.onUnhandledException.asObservable();
  isErrorHandled = false;

  handleError(errorObj) {
    if (this.isErrorHandled) {
      return;
    }
    
    this.onUnhandledException.next(errorObj);
  }
}

在我的 Handler.service.ts 中,我订阅了 onUnhandledException$ observable:

constructor(
  @Inject(ErrorHandler) private errorHandler: CustomErrorHandler,
  private zone: NgZone
) {
  this.errorHandler.onUnhandledException$.subscribe({
    next: (error) => {                
      this.shutdownApplication();
    }
  });
}

问题: 当后端抛出异常时,它会正确调用handleError()并在Angular 18浏览器构建系统中发出异常。然而,在新的 Angular 18 构建系统中,handleError() 方法似乎根本没有被触发。

问题:

  • Angular 18 新构建系统中的哪些变化可能会产生影响
    我的自定义错误处理程序的行为?
  • 如何确保未处理的异常被 new 中的 CustomErrorHandler 捕获
    构建系统?
  • 是否有任何额外的配置或设置步骤 使用新的构建系统在 Angular 18 中进行错误处理需要吗?

任何见解或解决方案将不胜感激!

注意:我还在 main.ts 文件中导入了 zone.js

angular error-handling
1个回答
0
投票

在发出之前不会订阅可观察对象。因此您没有收到事件。由于您正在使用服务,您只需通过依赖注入添加服务并直接调用该方法即可,这将消除计时问题。

@Injectable({
  providedIn: 'root',
})
export class HandlerService {
  constructor() {}

  shutdownApplication() {
    alert('shutdownApplication');
  }
}

@Injectable()
export class CustomErrorHandlerService extends ErrorHandler {
  onUnhandledException$: Subject<any> = new Subject<any>();
  constructor(private handlerService: HandlerService) {
    super();
  }

  override handleError(error: Error) {
    this.handlerService.shutdownApplication();
    console.log('Via Custom Error Handler: ' + error.toString());
    // super.handleError(error);
  }
}

完整代码:

import { Component, ErrorHandler, Inject } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class HandlerService {
  constructor() {}

  shutdownApplication() {
    alert('shutdownApplication');
  }
}

@Injectable()
export class CustomErrorHandlerService extends ErrorHandler {
  onUnhandledException$: Subject<any> = new Subject<any>();
  constructor(private handlerService: HandlerService) {
    super();
  }

  override handleError(error: Error) {
    this.handlerService.shutdownApplication();
    console.log('Via Custom Error Handler: ' + error.toString());
    // super.handleError(error);
  }
}

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h1>Hello from {{ name }}!</h1>
    <a target="_blank" href="https://angular.dev/overview">
      Learn more about Angular
    </a>
  `,
})
export class App {
  name = 'Angular';

  ngOnInit() {
    throw new Error('Thrown from AppComponent');
  }
}

bootstrapApplication(App, {
  providers: [
    {
      provide: ErrorHandler,
      useClass: CustomErrorHandlerService,
    },
  ],
});

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.