【问题标题】:Is it possible to modify Error's constructor so that it includes the context in which the error was thrown?是否可以修改 Error 的构造函数,使其包含引发错误的上下文?
【发布时间】:2014-07-29 16:58:28
【问题描述】:

说我疯了,但我希望所有 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

【问题讨论】:

  • 您可以创建自己的自定义错误构造函数,该构造函数接受用于填充context 属性的参数。然后在你的代码中,就像throw new CustomError(this, 'muted!');

标签: javascript node.js error-handling


【解决方案1】:

在抛出错误之前简单地将属性附加到您的错误(也许用一个不错的函数包装它):

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 指出的那样,使用帮助程序时,堆栈跟踪关闭了一个。如果你关心,你可以写出一个更长但更正确的助手:

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 属性(请参阅 this article 以获得解释)。其余的都是样板文件。

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

【讨论】:

  • 您在构造函数中创建 new Error 的事实意味着您捕获了错误的堆栈跟踪(太低了一级),可能需要修复它。
  • @BenjaminGruenbaum 感谢您的修改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 2019-02-26
  • 2014-06-30
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
相关资源
最近更新 更多