何时以及为什么创建自定义异常是好的



我正在开发一个具有不同类型错误、服务和域概念的复杂应用程序。

为了投掷";对象";错误,我想到了两种不同的方法:

  1. Object.assign()应用于Error对象(如果我只需要抛出一个或几个遵循此形式的错误,这是一个简单的选项(:

function f() {
const err = new Error();
Object.assign(err, {
name: "ServiceError",
code: "service/some-string-code",
message: "Some message",
});
throw err;
}
try {
f();
} catch(err) {
console.log(err instanceof Error);
}

  1. 创建自定义错误(扩展Error类(

class MyServiceError extends Error {
constructor(code, message) {
super(message);

this.name = "ServiceError";
this.code = code;
}
}
function f() {
const err = new MyServiceError("service/some-string-code", "Some message");
throw err;
}
try {
f();
} catch(err) {
console.log(err instanceof Error);
console.log(err instanceof MyServiceError);
}

两者之间的利弊是什么;自定义错误定义";。

此外,如果我选择第二种方法,我似乎需要为不同的域概念、服务等创建多个CustomError类,以实现对称代码和干净的架构。。。(??(反过来,我认为这是在重新发明轮子并添加不必要的代码,因为也许并不是应用程序的所有概念都需要自定义类型的异常。

这两种做法在JavaScript中都有效吗?

注意:抛出对象或字符串或类似的东西对我来说真的很糟糕,因为我们无法获得堆栈跟踪、验证实例等。

// This seems bad to me. Isn't it an anti-pattern?
throw {
code: "",
message: "",
name: ""
}

Object.assign方法的健壮性较差,更像是一种黑客攻击,最好创建自定义错误类。关于SO.已经有了深入的讨论

如果您想使用额外的字段,最多可以为内部错误引入2-3个自定义类,但即使这样也常常会有些过头:

  • NetworkError的一个,带有位置、路径和状态
  • 一个用于具有组件和有问题的数据状态的UiError,可能还有一个用于i18n的消息代码
  • 和一个通用RuntimeError或类似物,用于未知病例

对每个潜在事件都有一个错误类是没有意义的。与Java不同,JavaScript中没有检查异常,目标是在不过度设计的情况下,只拥有足够的数据来解决问题。如果你能有意义地捕获并在对话框中显示比message字符串所能容纳的更多的数据,那就去做吧

设计自定义错误时,请从处理和显示这些信息的位置和方式开始。然后看看你是否可以轻松地将这些数据收集到你扔的地方。如果你没有全局错误对话框或集中的错误报告,也许只有默认的错误就足够了,你可以将所有数据放入消息中。

有一种特殊情况,当您希望使用错误作为控制逻辑的手段时。尽量避免,JavaScript非常灵活,不使用throw作为让上层选择不同执行路径的方式。然而,它有时被用来重新尝试网络请求,然后它应该有足够的数据。

内置错误对象已经有以下字段:

  • 名称
  • 消息
  • 烟囱

在每个错误中,stackmessage是帮助解决问题的两条关键信息。因此,当你重新投掷它时,使用这样的东西(对于所有非IE(是很重要的:

catch (err) {
throw new Error('New error message with added info', { cause: err });
}

最后,它有助于检查其他人在做什么:

  • GraphQL的GraphQLError
  • VueJS中的错误处理挂钩(它没有自定义错误(

而且,JavaScript不仅有Error,还有:

  • 评估错误
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URI错误
  • 聚合错误

您也可以在适当的时候投掷它们。

请注意,大多数处理视图的UI框架都没有自定义错误类,也不需要。

相关内容

最新更新