是否可以修改 Error 的构造函数,使其包含引发错误的上下文?



说我疯了,但我希望所有JavaScript错误在抛出时都能暴露this的上下文。很难用英语解释,更容易用代码解释我想要的:

var Person = function() {
    this.name = 'Chuck';
}
Person.prototype.speak = function() {
    throw new Error('muted!');
    console.log('My name is', this.name);
}
var person = new Person();
try {
    person.speak(); 
}
catch(error) {
    console.log(error.context.name, 'could not speak.');
}

我是否有可能自动填充error.context属性,使上面的代码能够工作?我愿意接受任何疯狂的技巧,并使用下一个版本的JavaScript或node.js。

编辑:我想在不使用自定义错误的情况下做到这一点。这样我就可以捕获任何非自定义错误,并且仍然可以访问context

只需在抛出错误之前附加属性(可能用一个漂亮的函数包装它):

var obj = {
    foo : 'thingonabob',
    ouch : function () {
        var err = new Error();
        err.context = this;
        throw err;
    }
};
try {
    obj.ouch();
}
catch (e) {
    console.error('The darned %s is at it again!', e.context.foo)
}

一个可能的辅助函数:

function ContextifiedError (message, context) {
    var err = new Error(message);
    err.context = context;
    return err;
}

然后是throw ContextifiedError('something', this)

编辑:正如@BenjaminGruenbaum所指出的,当使用helper时,堆栈跟踪是关闭的。如果您关心,您可以编写一个更长但更正确的帮助器:

function ContextifiedError (message, context) {
    this.context = context;
    this.type = 'ContextifiedError';

    Error.call(this, message);
    if (Error.captureStackTrace) {
        Error.captureStackTrace(this, this.constructor);
    }
}
ContextifiedError.prototype = Error.prototype;
ContextifiedError.prototype.constructor = ContextifiedError;

Error.call用于调用我们自己的"父构造函数"。在现代浏览器上,Error.captureStackTrace确保我们有一个正确的.stack属性(请参阅本文以获得解释)。

然后你可以throw new ContextifiedError('something', this)

最新更新