我想在我的JS代码中抛出一些东西,我想让它们成为instanceof Error,但我也想让它们成为其他东西。
在Python中,通常会子类化Exception。
在JS中应该做什么?
我想在我的JS代码中抛出一些东西,我想让它们成为instanceof Error,但我也想让它们成为其他东西。
在Python中,通常会子类化Exception。
在JS中应该做什么?
当前回答
为了避免针对每种不同类型的错误的样板文件,我将一些解决方案的智慧结合到createErrorType函数中:
function createErrorType(name, init) {
function E(message) {
if (!Error.captureStackTrace)
this.stack = (new Error()).stack;
else
Error.captureStackTrace(this, this.constructor);
this.message = message;
init && init.apply(this, arguments);
}
E.prototype = new Error();
E.prototype.name = name;
E.prototype.constructor = E;
return E;
}
然后,您可以轻松地定义新的错误类型,如下所示:
var NameError = createErrorType('NameError', function (name, invalidChar) {
this.message = 'The name ' + name + ' may not contain ' + invalidChar;
});
var UnboundError = createErrorType('UnboundError', function (variableName) {
this.message = 'Variable ' + variableName + ' is not bound';
});
其他回答
我不喜欢所有其他的答案,太长,太复杂,或者没有正确地跟踪堆栈。这里是我的方法,如果你需要更多的自定义道具,将它们传递给构造函数,并像name一样设置它们。
class CustomError extends Error {
constructor (message) {
super(message)
// needed for CustomError instanceof Error => true
Object.setPrototypeOf(this, new.target.prototype);
// Set the name
this.name = this.constructor.name
// Maintains proper stack trace for where our error was thrown (only available on V8)
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor)
}
}
}
// create own CustomError sub classes
class SubCustomError extends CustomError{}
// Tests
console.log(new SubCustomError instanceof CustomError) // true
console.log(new SubCustomError instanceof CustomError) // true
console.log(new CustomError instanceof Error) // true
console.log(new SubCustomError instanceof Error) // true
throw new SubCustomError ('test error')
在ES6:
class MyError extends Error {
constructor(message) {
super(message);
this.name = 'MyError';
}
}
源
这并不复杂,但我个人认为这是扩展错误的最简单方法。
export default class ExtendableError extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
}
}
创建一个名为ExtendableError的实用程序类。这个实用程序类的目的是与普通的Error类类似,但在默认情况下将name属性更改为类的名称,因此很容易扩展错误。
现在,如果您想扩展一个错误,它只需要一行。
class MyError extends ExtendableError {}
除了标准的message属性,JavaScript现在支持将特定的错误原因作为可选参数添加到error构造函数中:
const error1 = new Error('Error one');
const error2 = new Error('Error two', { cause: error1 });
// error2.cause === error1
在节点v16.9.0中提供。 适用于Chrome, Firefox和Safari(见浏览器兼容性版本)
Crescent Fresh的答案是误导性的。尽管他的警告是无效的,但还有其他一些限制他没有提到。
首先,Crescent的“警告:”段落中的推理没有意义。这种解释意味着,与多个catch语句相比,编码“一堆if (error instanceof MyError) else…”在某种程度上是累赘或冗长的。单个catch块中的多个instanceof语句与多个catch语句一样简洁——干净简洁的代码,没有任何技巧。这是模拟Java出色的特定于可抛出子类型的错误处理的好方法。
WRT“显示子类的消息属性没有得到设置”,如果使用正确构造的Error子类,则不会出现这种情况。要创建自己的ErrorX Error子类,只需复制以"var MyError ="开头的代码块,将"MyError"改为"ErrorX"。(如果您想向子类添加自定义方法,请遵循示例文本)。
The real and significant limitation of JavaScript error subclassing is that for JavaScript implementations or debuggers that track and report on stack trace and location-of-instantiation, like FireFox, a location in your own Error subclass implementation will be recorded as the instantiation point of the class, whereas if you used a direct Error, it would be the location where you ran "new Error(...)"). IE users would probably never notice, but users of Fire Bug on FF will see useless file name and line number values reported alongside these Errors, and will have to drill down on the stack trace to element #1 to find the real instantiation location.