2012-06-02 74 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。