将 Array 与 Error 组合为单一类型

Posted

技术标签:

【中文标题】将 Array 与 Error 组合为单一类型【英文标题】:Combine Array with Error in a single type 【发布时间】: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);
;

【问题讨论】:

【参考方案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。但是如果他们改变它,你将来可能会遇到问题。

以上是关于将 Array 与 Error 组合为单一类型的主要内容,如果未能解决你的问题,请参考以下文章

将来自同一表的单独查询组合为单独的列

Python数据结构与算法---数组array

Python数据结构与算法---数组array

如何通过抽象将使用 Diesel 的多个功能组合为一个?

将两个查询与计数函数组合为一个结果集

将 2 列与其他列组合为 1