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

Kir*_*met 1 javascript error-handling node.js

叫我疯了,但是我希望所有的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.');
}
Run Code Online (Sandbox Code Playgroud)

我可以自动填充error.context属性,以便上面的代码可以工作吗?我对任何疯狂的技巧和使用下一个版本的JavaScript或node.js持开放态度.

编辑:我想在不使用自定义错误的情况下执行此操作.这样我可以捕获任何非自定义错误,仍然可以访问context.

Zir*_*rak 6

只需在抛出属性之前将属性附加到错误中(可能用一个很好的函数包装它):

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)
}
Run Code Online (Sandbox Code Playgroud)

一个可能的辅助函数:

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

    return err;
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:正如@BenjaminGruenbaum指出的那样,使用帮助程序时堆栈跟踪会被一个关闭.如果你在乎,你可以写出一个更长但更有道理的帮手:

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;
Run Code Online (Sandbox Code Playgroud)

Error.call是我们自己拨打我们的"父亲的构造函数".Error.captureStackTrace在现代浏览器上,确保我们拥有正确的.stack属性(请参阅此文章以获得解释).其余的是样板.

然后就可以了throw new ContextifiedError('something', this).