【发布时间】:2021-11-26 19:16:22
【问题描述】:
我正在开发一个具有不同类型错误、服务和域概念的复杂应用程序。
为了抛出“对象”错误,我想到了两种不同的方法:
- 将
Object.assign()应用于一个错误对象(如果我只需要在此表单后面抛出一个或几个错误,这是一个简单的选择):
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);
}
- 创建自定义错误(扩展 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: ""
}
【问题讨论】:
-
“也许不是应用程序的所有概念都需要自定义类型的异常。”你显然只需要针对不同的类型或问题的错误.不是
MyClassOneError、MyClassTwoError等。如果你有一个支付系统,它可能会抛出一个PaymentError来表示来自许多地方的支付的众多问题之一。或者这可能没用,您可以使用某种OperationError。 -
@VLAZ,例如,如果我正在扩展一项服务,这会抛出我已经定义的
PaymentErrors(这是一个不可导入的class(不是由库导出)),它可能是只为新添加的功能(即 PaypalPaymentError)定义“特定错误类”是个好主意吗? -
视情况而定。您想要专门处理这些问题吗?如果要像其他付款错误一样处理它们,那么您只需要一个
paymentType字段或类似字段,从而使用相同的基本错误,但使其带有一些相关信息。如果每种不同类型的错误需要单独的内容,那么您可以创建PaypalPaymentError、AmazonPaymentError等,但这必须是有意义的,例如,每个都有不同的字段和/或将完全不同地处理。