2009-12-10 22 views
1

這個標題乞求更多的解釋。您想如何暴露錯誤處理的API?

基本上,我正在推出一個API,將一個Web服務包裝在一個好的角色模型中。此模型公開以下形式:

var obj = MyRemoteResource.GetForId(1234, SourceEnum.ThatSource); 
ApiConsumerMethod(obj.SomeProperty); //SomeProperty is lazily loaded, and often exposes such lazily loaded properties itself 
... etc ... 

RemoteResources *(每個RemoteResources都有多個不同的屬性)。有真正積極的緩存進行,並要求限制,以防止無意DOS服務器(並取消呼叫者的IP被禁止)。

我已經有了所有這些代碼的工作,但我目前在處理錯誤方面做得並不多。基本上,如果API的使用者提供了無效的ID,Web服務器關閉,連接超時或發生大量請求層錯誤,則在訪問屬性時會發生異常。

我認爲這遠遠不夠理想。

所以我的問題是,我應該如何包裝這些錯誤,以便這個API的用戶來管理它們呢?

一些路線我已經考慮:

  • 只是包裝在一些API上定義的所有異常,並且拋出記錄它們。
  • 公開靜態ErrorHandler類,該類允許用戶爲特定錯誤註冊通知回調;如果沒有針對特定錯誤進行註冊,則會回到上述行爲。**
  • 錯誤時爲null,並設置LastErrorCode

這些方法都有優點和缺點。我會欣賞他們的意見,以及我沒有想到的替代方案。

如果它影響討論的話,拋出這些例外的平臺類是WebClient。此外,WebClient的使用足夠抽象,如果需要,可以很容易地用其他一些下載方案替換。

*這就是說,許多不同種類的

**這將是...奇怪。但它映射到失敗的全球性。這是迄今爲止我最不喜歡的想法。

回答

2

我不會實現奇特的錯誤技術(如事件和類似的東西)。判斷在哪裏以及如何使用異常並不容易,但這不是實現其他內容的理由。

當你通過一個不存在的id請求一個對象時,你有什麼要告訴調用者這個?如果你只是返回null,客戶端知道它不存在,沒有什麼可說的。

例外強制呼叫者關心它。所以他們應該只用於要求調用者做特別的事情。例外可以提供信息爲什麼不起作用。但如果這是一個「錯誤」,用戶也可以忽略,一個例外不是最好的選擇。

有兩種常見的例外情況。

  • 使用返回值提供有關操作結果的信息。例如,logon可能會返回LogonResult而不是拋出異常。
  • 編寫兩個方法,一個拋出異常,另一個(Try ...)返回一個布爾值。來電者決定是否要忽略「錯誤」。
+0

這比我的回答好得多:o) – hhravn 2009-12-10 07:53:41

+0

該API的延遲加載特性使得很難確定id是否有效。一個完全有效的用例是從ID(例如緩存在一個文件中)構造一大組項目,然後遍歷一組屬性。只有訪問了一個屬性,ID的有效性才能確定。 – 2009-12-10 08:40:28

0

我喜歡在發生不良事件時拋出異常。例外是(對我來說)通常的方式來說明出現了問題,並且我發現它更直觀地被捕獲,而不是檢查返回值爲null並檢查另一個屬性以查看出了什麼問題..

+0

heh。我寧願檢查返回值而不是拋出異常。我將異常與完全意想不到的事情聯繫起來只是去展示我猜想的不同編程風格。 – Alex 2009-12-10 09:32:23

2

就我個人而言,我相信這完全取決於您的API最終用戶嘗試執行的操作。如果是這樣,你應該讓他們決定如何處理錯誤。

最近,當處理CSV文件(非常容易出錯)時,我使用了一個允許您定義異常行爲的API。您可以忽略錯誤,替換爲某個默認值/操作,或將它們傳遞給事件處理程序。

我真的很喜歡讓最終用戶決定如何處理內部異常的方法,因爲除非您的API非常具體,否則難以搶佔所有場景。

+0

基本上我同意,但是CSV解析比特定的服務器API更普遍。 – 2009-12-10 08:41:16

+0

我不認爲你的建議是真的不同。例如,LogonResult對象可能會包含一些處理以吞下異常並設置指定錯誤發生的屬性。我寧願通過一個簡單的屬性來看到它,而不是將它們放在一個包裝類型中,因爲在很多情況下,最終用戶只會將這些LogonResult值映射到它們自己的ApplicationXLogonResult(或直接映射到GUI /命令行/日誌文件)。如果你把東西留給用戶,那麼他們可以直接使用這些值而不用處理這些其他類型。 – Alex 2009-12-10 09:28:31