8

我有一个这样定义的全局错误处理程序(简化/专有信息已清理):

export class ErrorsHandler extends CommonBase implements ErrorHandler {
  constructor(protected loggingService: LoggingService,
              private coreService: CoreService {

    super(loggingService);
  }

  handleError(error: Error) {
    if (error && error.stack && (error.stack.indexOf(Constants.PACKAGE_NAME) >= 0)) {
      this.logSystemError(error, true);
      this.coreService.showSystemError(error, this.owner);
    }
    else {
      // Rethrow all other errors.
      throw error;
    }
  }

在我的模块(并且只有我的模块)中,它被注册为提供者:

export function errorHandlerFactory(loggingService: LoggingService, coreService: CoreService) {
  return new ErrorsHandler(loggingService, coreService);
}

providers: [
    { provide: ErrorHandler, useFactory: errorHandlerFactory, deps: [LoggingService, CoreService] }
]

我的模块被其他人使用,我们一起组成了一个大型应用程序。我的问题是所有脚本错误都被捕获,即使我尝试过滤那些仅与我的模块/包相关的错误,因为过滤是在handleError(). 即使我重新抛出了与我无关的错误(在else上面),其他模块/包的开发人员仍在抱怨我正在全局捕获所有内容,并且他们得到的重新抛出的错误已经丢失了某些上下文/信息。

所以问题是,是否有可能以某种方式限制我的错误处理程序的范围以仅捕获和处理源自我的模块/包的脚本错误(同时完全忽略应用程序中的所有其他脚本错误)?

经过大量的谷歌搜索,我能想到的唯一选择是try/catch到处放,这是我想尽可能避免的事情。

4

2 回答 2

3

You can try creating a service - ErrorService to share the context and then throw the error from the global error handler. You can then catch the error from the required Component.

PFB the steps:

  1. Create the error service as follows:

    @Injectable({
        providedIn: 'root'
    })
    export class ErrorService {
        constructor() {}
    
        private error = new BehaviorSubject(new Error());
        error_message = this.error.asObservable();
    
        changeMessage(e: Error) {
            this.error.next(e);
        }
    }
    
  2. throw the error from the handleError method in ErrorHandler. PFB the snippet:

    handleError(error: Error) {
         if (error && error.stack &&(error.stack.indexOf(Constants.PACKAGE_NAME) >= 0)) 
         {
              this.logSystemError(error, true);
              this.coreService.showSystemError(error, this.owner);
         }
         else {
              //`errorService` is the `instance` for `ErrorService Component` 
              //imported in the defined `ErrorHandler`
              this.errorService.changeMessage(error);
              // Rethrow all other errors.
              throw error;
         }
      }
    
  3. Use try-catch to catch the error in your Component. Use error_message from ErrorService for the same.

于 2019-05-14T11:31:32.283 回答
1

我不知道CommonBase在做什么,因此我不确定这是否是一个可行的答案,但你可以做的一件事就是改变你ErrorsHandler的一点。如果你改变你的结构并从核心派生ErrorHandler而不是实现它的接口,你最终可能会得到这样的结果:

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

@Injectable()
export class ErrorsHandler extends ErrorHandler {

  constructor() {
    super();
  }

  handleError(error: any): void {
    if(error && error.stack && error.stack.indexOf("MyModule") >= 0) {
      console.log(`Uff, that was close. Got ${error}`);
      return;
    }
    super.handleError(error);
  }
}

我认为这会给您带来更高的可靠性,并且会正确传播错误。重新抛出错误无法以某种方式正常工作,但我不能 100% 确定确切原因。

我希望这会有所帮助!

于 2019-05-14T19:18:17.710 回答