【问题标题】:Combine Array with Error in a single type将 Array 与 Error 组合为单一类型
【发布时间】:2016-10-18 07:46:05
【问题描述】:

我有一个基于 Promise 的库(适用于 Node.js 0.10 - 6.x),其方法使用 Array 拒绝。

当使用Bluebird 时,会导致警告:a promise was rejected with a non-error

将数组包装成自定义错误类型很容易,但我想避免破坏库的向后兼容性。

是否有可能实现这样一个可以用作数组的对象,同时被Bluebird 视为Error 对象?

附加内容

当从 Error 继承时,我使用以下帮助程序与 Node.js 0.10 - 0.12 兼容:

function inherits(child, parent) {
    child.prototype.__proto__ = parent.prototype;
}

看看Bluebird 来源,也许有办法以某种方式规避其验证:

Promise.prototype._rejectCallback =
function(reason, synchronous, ignoreNonErrorWarnings) {
    var trace = util.ensureErrorObject(reason);
    var hasStack = trace === reason;
    if (!hasStack && !ignoreNonErrorWarnings && debug.warnings()) {
        var message = "a promise was rejected with a non-error: " +
            util.classString(reason);
        this._warn(message, true);
    }
    this._attachExtraTrace(trace, synchronous ? hasStack : false);
    this._reject(reason);
};

【问题讨论】:

    标签: javascript arrays node.js promise bluebird


    【解决方案1】:

    只要您的环境允许子类化Error,就可以!

    我在extending errors to create my own subtypes 时问过类似的事情,这本质上就是你想要做的。事实上,我已经做了类似的事情来创建包含响应状态代码的 HTTP 特定错误。

    假设您的环境确实允许class SubError extends Error(如果不允许,则有一种解决方法),您只需这样做:

    class ErrorWithData {
      constructor(msg, data = []) {
        super(msg); // this changes with the workaround
        this._data = [].concat(data); // make a copy for safety's sake
      }
    
      get data() {
        return this._data;
      }
    }
    

    如果您使用的旧版浏览器不允许您对 Error 进行子类化,则可以使用 @Mosho's answer 中的 shim 类,并将该示例中的 extends Error 替换为 extends ErrorClass

    NodeJS 将允许您使用extends Error from v4 并继续使用v6 having correct/full support。早期版本需要 Mosho 的解决方法。

    【讨论】:

    • 我刚刚更新了我的问题 - 它专门针对 Node.js (0.10 - 6.x)
    • 有些允许extends Error,有些不允许。根据kangax.github.io/compat-table/es6,v4 和 v5 需要 use strict(不正确),而 v6 通常允许子类化错误,但 v0.10 和 v0.12 不会。
    • 我已经在 Node.js 0.10 - 0.12 下使用 shim 进行子类化,它工作正常。我想它也可以在那里完成? :) function inherits(child, parent) { child.prototype.__proto__ = parent.prototype; }
    • 我相信Error 有一些额外的属性(如堆栈跟踪),如果您只是复制原型,这些属性将会丢失。你应该试试看。
    【解决方案2】:

    Javascript 不允许真正的多原型继承。

    您可以“扩展”Error,但子类不能同时是 instanceofErrorArray

    如果Bluebird 使用duck-typing,您可以尝试继承Array 对象并模拟Error 行为(接口和属性),但这在很大程度上取决于Bluebird 错误检查实现。

    我认为将数组值包装到错误属性/属性中会更好、更健壮。

    【讨论】:

    • is better and robust to wrap the array value into an Error - 正如我所说,我问这个问题的主要原因是避免破坏向后兼容性。
    • 因此您可以尝试使用错误接口(如跟踪属性等)对数组进行子类化。查看 Bluebird 的源代码,它不使用 instanceof Error。但是如果他们改变它,你将来可能会遇到问题。
    猜你喜欢
    • 2015-02-24
    • 2023-04-01
    • 2018-08-16
    • 1970-01-01
    • 2022-10-16
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    相关资源
    最近更新 更多