【问题标题】:Enrich a caught Error and rethrow in angular/typescript丰富捕获的错误并在角度/打字稿中重新抛出
【发布时间】:2020-09-24 12:02:59
【问题描述】:

我是前端开发的新手——我过去几年只做后端。我正在尝试删除帮助程序中的错误消音器,并使用更多信息重新抛出被吞下的错误。在自定义的 ErrorHandler 中,我将捕获错误端将信息发送到后端服务。我不知道如何以正确的方式做到这一点。 投掷部分(简体):

class Helper {
  public doStuff(input: string): string {
    try {
      return mightThrowAnException(input);
    } catch (err) {
      (err as any).inputData = input; // this destroys the error data
      throw err;
    }
  }
}

然后用

捕捉这个

export class GlobalErrorHandler extends ErrorHandler {

  constructor(
    private injector: Injector,
  ) {
    super();
  }

  public handleError(error: Error) {
    let loggingData: any = {
      errorMessage: error.message,
    }

    if (typeof (error as any).inputData !== "undefined") { // would like to replace this duck-typing, too
      loggingData = {
        ...loggingData,
        inputData: (error as any).inputData,
      }
    }

    // ... more stuff here

    console.log(loggingData); // will send the data to the logging server ITRL
  }
}

为了丰富我已经尝试使用@jsdevtools/ono包的错误:

class HelperWithOno {
  public doStuff(input: string): string {
    try {
      return mightThrowAnException(input);
    } catch (err) {
      throw ono(err, {inputData: input});
    }
  }
}

谁做了这项工作。不幸的是,TS linter 不喜欢使用symbol (https://github.com/JS-DevTools/ono/issues/13),所以我得到了一个红色的构建管道

在带有 Zend 的 PHP 中,我将创建一个类,该类在帮助程序的命名空间中扩展通用 Exception 并添加 inputData 属性。然后我将能够检查捕获的异常的类型并以所需的方式处理它。

但我对 Angular 和 TypeScript 还很陌生,不知道如何执行此任务。

  • 我可以扩展 Error 类但是
    • 是否需要手动从“上一个”错误中复制每个属性?还是我应该引入另一个属性previousError 来存储原始错误?
    • 在哪里(目录)存储类文件?
    • 我应该为错误创建一个可注入工厂吗?
    • 有经验的开发人员会在哪个模块中担任此类?
  • 等到ono 修复
  • 还有其他最佳做法吗?

【问题讨论】:

  • 顺便说一句:我使用stackblitz.com/edit/typescript-fgvbck 编写这篇文章的来源。
  • 这个错误处理程序的目的是什么?是什么阻止您将错误从 catch 发送到执行所有处理的服务?我还强烈建议不要在打字时欺骗打字稿,创建一个包含您的输入和错误的界面。
  • 调用函数(调用者)可能知道错误并可以捕获异常。如果调用者(决定)没有捕获异常,全局 ErrorHandler 应该记录失败。
  • 我想创建接口,但不知道为此目的正确放置文件的位置(这就是问题 在哪里(目录)存储类文件?)

标签: javascript angular typescript error-handling


【解决方案1】:

没有答案,所以我只是发布我的解决方案;希望有人能告诉我它是否错误/有问题并提出更好的解决方案。

我在类Helper 的目录下创建了一个名为errors 的文件夹。在这个目录中有一个类的文件

export class ProcessError extends Error {
    public inputData: string;
    public originalError: Error;

    public constructor(error: Error, inputData: string) {
        const errorAsAny = error as any;

        if ('fileName' in errorAsAny) {
            // Firefox specific
            if ('lineNumber' in errorAsAny) {
                // @ts-ignore
                super(error.message, errorAsAny.filename, errorAsAny.lineNumber);
            } else {
                // @ts-ignore
                super(error.message, errorAsAny.filename);
            }
        } else {
            super(error.message);
        }

        // Let's apply some magic you can find at https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
        Object.setPrototypeOf(this, ProcessError.prototype);

        this.originalError = error;
        this.inputData = inputData;
        this.stack = error.stack.split('\n').join('\n'); // materialize stack; not sure whether required
    }
}

现在我可以用

抛出异常
class HelperWithCustomError {
  public doStuff(input: string): string {
    try {
      return mightThrowAnException(input);
    } catch (err) {
      throw new ProcessError(err, input);
    }
  }
}

并检查实例而不是使用

进行鸭式打字
if (error instnaceof ProcessError)

【讨论】:

  • 对于任何过来并想知道的人来说,这确实是丰富 javascript / typescript 错误的正确方法。
猜你喜欢
  • 1970-01-01
  • 2017-05-29
  • 2012-10-17
  • 2017-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-18
  • 2017-10-31
相关资源
最近更新 更多