2012-06-02 43 views
5

我正在考虑流量控制的最佳实践。我应该走哪条路?Ruby流控制:抛出异常,返回零或让它失败?

1)不检查任何东西,让程序失败(干净的代码,自然错误消息):

def self.fetch(feed_id) 
    feed = Feed.find(feed_id) 
    feed.fetch 
    end 

2)通过返回零失败默默(但是,“清洁守则”说,说你不应该返回null):

def self.fetch(feed_id) 
    return unless feed_id 
    feed = Feed.find(feed_id) 
    return unless feed 
    feed.fetch 
    end 

3)抛出异常(因为它特殊的不找到ID饲料):

def self.fetch(feed_id) 
    raise ArgumentError.new unless feed_id 
    feed = Feed.find(feed_id) 
    raise ArgumentError.new unless feed 
    feed.fetch 
    end 

换言之:我应该主动使用警戒条件,还是依赖Ruby/Rails方法并让它们抛出异常,如果发生错误,会更好?

+1

如果这个ActiveRecord,'find'会在id不存在时触发,'find_by_id'不会触发。 – tokland

回答

6

1)不检查任何东西,让程序失败(干净的代码, 天然错误消息):

它的确定为“让程序失败”与已知的,记录异常,但因为你试图使用nil对象而得到一个不愉快的NoMethodError只是粗心大意。在您的具体的例子,ActiveRecord#find提出了一个记录ActiveRecord::RecordNotFound例外,所以国际海事组织这是要走的路:

def self.fetch(feed_id) 
    Feed.find(feed_id).fetch 
end 

2)通过返回零(但是,“清洁守则”说失败默默,那 你应该从来没有返回null):

作为一般性建议,这很好,但Ruby被挤满了方法,返回nil;这没关系(再次,只要它被记录),它只是意味着“没有”(并允许非常紧凑的模式something_that_can_be_nil || another_value)。在这种情况下,我会写简明使用伊克的maybe

def self.fetch(feed_id) 
    Feed.find_by_id(feed_id).maybe.fetch 
end 

3)抛出异常(因为它的特殊找不到由 ID饲料):

是的,但后来让该方法提高着名的RecordNotFound例外,而不是自定义的例外(除非要抽象说明您使用AR的事实,这可能非常麻烦)。

2

我认为正确的答案是:这取决于。用户应该从不会从框架中遇到任何错误消息。你必须随时准备处理这些例外情况。选择是你所有的(如果它不是一个外部使用的接口或其他东西)。

如果你采取第一条路线,我认为你应该拳头查询是否有任何饲料与该ID存在,然后尝试获取它。如果Feed在两者之间消失,那么这可能是一个真正需要报告的问题。第三个基本上是一样的。您需要确保您处理了每种情况,并且抛出异常可以帮助防止用户看到错误。

第二种解决方案基本上是这样,但是具有内部处理。用零表示有问题。它也必须被处理,报告给用户,或者其他东西。缺点是,如果你忘记了这一点,你可能会误导用户。

我会使用第一种方法,以确保它存在之前的额外检查。但这取决于使用情况。

+0

是的,它取决于。如果这是一个致命的错误,那么操作必须成功才能使程序继续运行,让它失败或抛出异常。否则,只返回零 – texasbruce

2

我会去干净的版本。

如果你没有给fetch方法提供feed_id,ruby本身会增加ArgumentError: wrong number of arguments(0 for 1),所以#3的第一部分是毫无意义的。

如果不提供一个有效的feed_id,则Feed.find(feed_id)通话将引发一个不同的异常,最有可能与ActiveRecord::RecordNotFound的消息或者说,它无法找到与所提供的ID的饲料,或者如果没有提供ID (feed_id参数为nil),它无法找到没有ID的提要。

对我来说,似乎有点愚蠢的调用方法与feed_id = nil,所以我可能会说,“如果你发送无效的输入,它可能会破坏”,在这种情况下,我认为ActiveRecord::RecordNotFound会给你多少更多有关出错的信息比如果您提出ArgumentError

返回一个空值很少是一件好事,因为它不会告诉你究竟发生了什么错误。因此,我也会排除#2。