将 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
,但子类不能同时是 instanceof
和 Error
和 Array
。
如果Bluebird 使用duck-typing,您可以尝试继承Array
对象并模拟Error
行为(接口和属性),但这在很大程度上取决于Bluebird 错误检查实现。
我认为将数组值包装到错误属性/属性中会更好、更健壮。
【讨论】:
is better and robust to wrap the array value into an Error
- 正如我所说,我问这个问题的主要原因是避免破坏向后兼容性。
因此您可以尝试使用错误接口(如跟踪属性等)对数组进行子类化。查看 Bluebird 的源代码,它不使用 instanceof Error
。但是如果他们改变它,你将来可能会遇到问题。以上是关于将 Array 与 Error 组合为单一类型的主要内容,如果未能解决你的问题,请参考以下文章