7

我正在开发一个供其他人使用的 pub/sub Mediator 库,但我不知道如何处理错误。

这是一段示例代码:

/**
 *
 * @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});
}

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

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

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


所以我的问题是...

在这种特定情况下,考虑到我正在为其他人开发 javascript 库,我应该:

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

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

4

3 回答 3

1

我想这个答案更多的是我的观点和我所遵循的。您必须问自己是否应该返回抛出错误并让您的库的使用者处理错误。如果错误是无法恢复的,则无需抛出错误(在 JS 中)。你的库应该能够优雅地回退到替代方案,但如果它不能为某个函数做到这一点,它应该返回 undefined。大多数 JS 开发人员确实会检查未定义,并且在使用库函数时这样做是很常见的做法。如果无法处理事件,通常在事件处理程序中返回 false。

于 2013-02-07T16:05:38.913 回答
0

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

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

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

于 2013-02-07T16:32:53.147 回答
0

错误和异常应该完全停止执行并通知调用者。“抛出错误以防止进一步的错误传播?” 如果在这种情况下不应该执行您的代码,则完全是编写选择。

尽管如此,如果您预计某些内容会被错误传递,您可以返回一些特殊值并在文档中进行描述。默认值被开发人员广泛使用,这并不直观,但大多数情况下都有效:

/*
* ...
* Returns a Socket if found, otherwise undefined
*/

function FindSocketOrUndefined(): Socket|undefined {
...
return undefined
}
于 2021-04-13T15:09:23.110 回答