【问题标题】:How to limit scope of ErrorHandler?如何限制ErrorHandler的范围?
【发布时间】:2019-09-22 07:42:07
【问题描述】:

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

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 放在任何地方,这是我想尽可能避免的事情。

【问题讨论】:

  • angular.io/guide/… 您有 2 个选项,延迟加载模块或在组件中提供。懒加载更可取
  • 你想单独处理 HTTP 调用的错误还是整个模块的错误?
  • @ManojRamanan 整个模块。
  • 你检查过你的ErrorHandler是否真的进入else了吗?
  • 这是一个您可能需要考虑的有趣设计模式:refactoring.guru/design-patterns/chain-of-responsibility。您可以为用户提供 API 来添加他们自己的错误处理程序,而不是抛出错误。这样就不会重新抛出错误,并且用户可以访问完整的上下文

标签: angular typescript error-handling angular7 angular-errorhandler


【解决方案1】:

您可以尝试创建一个服务 - ErrorService 来分享context,然后throw 来自global error handler 的错误。然后,您可以从所需的Component 中获得catch 的错误。

PFB步骤:

  1. 如下创建错误服务:

    @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 来自ErrorHandler 中的handleError 方法的错误。 PFB sn-p:

    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. 使用try-catch 捕获Component 中的错误。使用来自ErrorServiceerror_message 相同。

【讨论】:

    【解决方案2】:

    我不知道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% 确定确切原因。

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      相关资源
      最近更新 更多