在开发库时,我们应该抛出错误/异常吗?

Tiv*_*vie 6 javascript debugging error-handling shared-libraries

我正在开发一个供其他人使用的发布/订阅中介库,但我不知道如何处理错误。

这是一段示例代码:

/**
 *
 * @param String channel Channel to subscribe
 * @param String|function callback Function name or callback
 * @param String context Context to bind function to
 * @param Boolean once True to subscribe once
 **/
this.subscribe = function (channel, callback, context, once) {

    if (!_.isObject(context)) {
         context = window;
    }

    if (!_.isFunction(subscription) && !_.isFunction(context[subscription])) {
        throw new Error('Function passed as callback to channel subscription named  ' + channel + ' seems invalid!');
    }

    // Everything ok, add to channels object
    channels[channel].push({fn: subscription, context: context || this, once: once});
}
Run Code Online (Sandbox Code Playgroud)

此方法是库的一部分。它的 API 需要一个通道名称和一个有效的回调(函数名称、lambda 或回调)。

如果通道参数不是字符串,则库很容易停止。如果传递了无效的上下文,则假定为 window。这两个参数中的错误很容易调试。

但是,如果传递了无效的回调,它会传播错误,直到触发事件(进行通道发布)。在 pub/sub 系统中,这可能成为调试的噩梦,例如,如果事件很少被触发。


所以我的问题是...

在这个特定场景中,考虑到我正在为其他人开发 javascript 库,我应该:

  • 抛出错误以防止进一步的错误传播?
  • 返回 false/undefined/-1 并且不注册订阅?
  • 照常进行,让它死在某个地方,将调试留给第三方开发人员

注意:有一个类似的问题,但我的情况有点不同,所提供的答案并没有让我放心。

Ber*_*rgi 0

应避免选项#3。至少,return false;。您甚至可以注册无效的回调,期望也不会发布任何事件(因为出现了问题)。这种“如果不是一切都出了问题,则静默失败”可能并不真正适用于您的发布/订阅示例,但可能有它的用例。

选项#2 听起来不错。它以某种方式使callback参数显式可选,这可能是您的库的一个功能 - 如果用户不确定自己是否有订阅的理由,如果您无论如何都要做的话,他可以省略该测试。您可以将其与console.warn()调试版本中的消息结合起来。

如果确实发生了意外情况,则应选择选项#1。它允许您失败并显示非常描述性的自定义错误消息。如果回调是一个真实的对象,但不可调用,或者通道参数是布尔值或其他东西,则可能是这种情况 - 取决于您的接口设计的封闭程度/您提供的重载程度(在您的情况下,您可以接受字符串例如,被评估为回调或通道字符串数组)。