包装捕获错误

Wraping caught errors

我在这方面找不到任何东西,所以我假设我正在搜索错误的东西,或者这不是一件常见的事情。

我正在编写一个基本库,它抽象了一些底层库。每个底层库都会抛出自己非常模棱两可的错误消息,这些消息对最终用户来说意义不大。有些还扩展了不同的属性。

目前我捕获了这些错误并抛出一个新错误,这对最终用户更有意义并且在结构上是一致的。但是,这会丢失原始错误的堆栈跟踪,我想保留它,因为它包含一些对最终用户有价值的信息。

起初我认为自定义错误 class 是保持类型检查的方法,所以我从类似

的东西开始
class WrappedError extends Error {
  readonly stack;

  constructor(message: string, error?: Error) {
    super(message);

    if (error?.stack) {
      this.stack = error.stack
    }
  }
}

但很快意识到,即使这有效(编辑:刚刚检查过,跟踪不会继续),那么 error.stack 将只包含从原始抛出到我的捕获和创建新 WrappedError - 之后的所有内容都会丢失。

这让我觉得我最后一个现实的选择是改变原始错误并重新抛出它

catch (error) {
  error.message = `Error reason due to such and such, but also; ${error.message}`
  throw error;
}

我不是突变的忠实粉丝。而且在这一点上,我非常喜欢从我的 class.

中获得一个自定义错误类型的想法

堆栈能否保留和继续?或者实现这一目标的最佳方法是什么?或者有没有在JS中使用的约定?

最近好像有点 native solution was added,所以一个干净的解决方案是

try {
  ...
} catch (error: unknown) {
  throw new Error('Error reason due to such and such', { cause: error });
}