2011-07-31 33 views
13

我有一個Scala幫助器方法,它目前試圖獲取一個URL並返回一個Option [String]與該網頁的HTML。更好地返回無或提取URL時引發異常?

如果有任何異常(格式不正確,讀取超時等),或者如果有任何問題,則返回無。問題是,拋出異常以便調用代碼能夠記錄異常,還是最好在這種情況下返回None?更好嗎?

+1

如果是輔助方法,我認爲它是私人的。如果它是私人的,那麼你是來電者。如果你是來電者,那麼你就是擁有關於應該發生什麼的所有信息的人,所以做任何你想要的。否則,請看Jean的答案。 – agilesteel

回答

32

創建異常很昂貴,因爲必須填寫堆棧跟蹤。投擲和捕捉異常也比正常回報更昂貴。考慮到這一點,你可能會問自己以下問題:

  • 你想調用者強制錯誤的處理?如果是這樣,不要拋出異常,因爲Scala沒有檢查異常機制,強制調用者捕獲它們。

  • 如果發生錯誤,是否要包含有關失敗原因的詳細信息?如果不是,您可以返回Option[A],其中A是您的返回類型,然後您將有Some(validContent)None,沒有其他解釋。如果是的話,你可以返回像Either[E, A]或斯卡拉茲Validation[E, A]。所有這些選項強制調用者以某種方式解開結果,同時按照自己的意願自由處理錯誤E。那麼E應該是什麼?

  • 您是否想在出現故障時提供堆棧跟蹤?如果是這樣,你可以可以返回Either[Exception, A]Validation[Exception, A]。如果你真的去除了例外,你會想要使用Try[A],其中兩種可能的情況是Failure(exc: Throwable)Success(value: A)。請注意,您當然會產生創建throwable的成本。如果不是,你可能只需要返回Either[String, A](並且要特別小心,以記住Right是否意味着成功或失敗 - Left通常用於錯誤,而Right用於「正確」值 - Validation也許更清楚)。如果你想可選返回堆棧跟蹤,你可以使用電梯的Box[A],這可能是Full(validContents)Empty沒有額外的解釋(非常類似於Option[A]了這裏),或表示Failure它可以存儲一個錯誤字符串和/或一個可拋(更多)。

  • 你也許想提供多種說明,說明它爲什麼失敗?然後返回Either[Seq[String], A]。如果你經常這樣做,你可能會想用Scalaz和Validation[NonEmptyList[String], A]來代替,它提供了一些其他的好東西。看看它的更多信息或退房these usage examples

+0

偉大的總結!就個人而言,我大部分時間都使用[String,...],但斯卡拉茲的驗證似乎更清晰。 –

1

我認爲,在這種情況下,如果重要的是要記錄異常,然後通過各種手段拋出的異常(也可能只是返回字符串而不是選項)。否則,你可能只是返回無。一個警告 - 可能會出現其他原因的例外情況,您無法預見,在這種情況下,編寫一段代碼可能會很危險。

你可以做的一件事就像Lift的Box系統。一個盒子本質上是一個選項,但添加了幾個功能:A Full就像一個SomeEmpty就像一個None,但電梯更進一步,有一個Failure,這就像一個Empty,但有一個原因/信息。

0

一般的經驗法則是「如果你能處理異常,處理它」。所以沒有足夠的上下文來猜測。您可以使用tryFetchUrl/fetchUrl對方法。

相關問題