2011-01-20 59 views
5

在方法中使用try-catch時,如果您希望應用程序繼續運行,即使出現錯誤,是否可以通過catch塊返回默認值作爲返回並記錄錯誤以供以後查看?嘗試 - 捕獲返回策略

例如:

public static string GetNameById(int id) 
{ 
    string name; 
    try 
    { 
     //Connect to Db and get name - some error occured 
    } 
    catch(Exception ex) 
    { 
     Log(ex); 
     name = String.Empty; 
    } 

    return name; 
} 

實施例2:

public static string GetIdByName(string name) 
{ 
    int id; 
    try 
    { 
     //Connect to Db and get id- some error occured 
    } 
    catch(Exception ex) 
    { 
     Log(ex); 
     id = 0; 
    } 

    return id; 
} 

是否好返回任何默認值(取決於該方法的返回類型... ???),使得需要這種方法的結果的應用邏輯不會崩潰,並繼續...

在此先感謝...

此致敬禮。

+2

我真的很喜歡這樣的需求:應用程序應該繼續,無論錯誤。繼續什麼?顯示一個空的名字?使用空鍵查找其他數據?當沒有數據庫連接時查找其他數據?在大多數情況下,唯一的方法就是停下來。 (除了像日誌記錄,如果日誌記錄失敗,你可能會繼續,這就是爲什麼LogMsg()等沒有返回值。) – 2011-01-20 13:43:29

+0

那麼你不能向用戶顯示錯誤,你不知道嗎? – Greg 2011-01-20 14:44:43

回答

0

最好記錄異常,然後重新磨光它,以便它可以在上層正確處理。

注:「記錄異常部分」當然是可選的,取決於你的操作策略有很多(?將您登錄一遍別處)

不是使應用程序不受swalowing異常崩潰的,最好讓他們通過並試圖找到他們爲什麼被拋在第一位的根本原因。

+0

-1。 OP指出要求具體的策略。我也有一些行動,如果可以「繼續工作」比「崩潰並讓建築物燒燬」更好。自動重啓並不總是一個問題。 NATURALLY人確實跟蹤和解決問題。特別是連接驅動程序可能想要處理那些時間....獲得1000條消息,如果以不可預見的方式破壞,則會有一條消息....鎖定消息和錯誤,可能會處理剩餘的消息。修復後重新加載數據。 – TomTom 2011-01-20 12:14:20

+0

@TomTom你沒有任何意義... – 2011-01-20 12:20:56

1

建議您只捕獲可以處理和恢復的錯誤。捕捉和消耗你無法處理的異常是不好的形式。但是,一些環境/應用程序定義嚴格的規則,違背了這種理想的行爲。

在這種情況下,如果您沒有選擇的話,我會說您可以按照自己喜歡的方式進行退貨 - 這取決於您的應用程序是否可以使用它們。

基於假設您的應用程序可以處理嘗試獲取ID的任何類型的失敗,那麼返回默認ID是一個足夠好的選擇。你可以進一步使用類似於特例模式的東西來返回空的/丟失的對象,但對於簡單的數據類型來說,這看起來沒有根據。

0

這很大程度上取決於上下文以及您調用方法的設計方式。我已經習慣像現在這樣在過去返回默認值,並且我只是在後來才明白它是深深的錯誤......

您應該想象catch塊在將日誌正確記錄後拋出異常,然後調用方法可能有另一個嘗試捕獲,並根據錯誤的嚴重程度可能會通知用戶或相應的行爲。

事實是,如果你返回一個空字符串,在某些情況下,可能是調用者「認爲」有一個空名稱的用戶,但可能會更好地通知用戶該記錄未找到, 例如。

取決於你的工作記錄,你處理它,而不是在所有漁獲你只能記錄異常這取決於你想要什麼樣的方式......

0

。如果你記錄異常對你很重要,但是其他所有事情都繼續工作,那麼這是我的誠實意見。

另一方面:如果發生異常,您必須確保這不會影響您的應用程序的進一步工作。

6

異常處理的建議是,大多數情況下,您應該只捕獲可以做某些事情的異常(例如,重試操作,嘗試不同的方法,提升安全性等)。如果您在全球範圍內在應用程序的其他地方進行了日誌記錄,則不需要這種捕獲日誌記錄。

個人 - 通常是 - 在這種情況下,我應該這樣做:

public static string GetNameById(int id) 
{ 
    string name; 
    try 
    { 
     //Connect to Db and get name - some error occured 
    } 
    catch(Exception ex) 
    { 
     Log(ex); 
     throw; // Re-throw the exception, don't throw a new one... 
    } 

    return name; 
} 

所以像往常一樣 - 它依賴。

不過,要注意其他的缺陷,比如調用方法沒有意識到出現了故障,並且繼續假設拋出異常的方法實際工作時繼續工作。在這一點上,你開始關於「返回代碼與拋出異常」的對話,你會在SO.com和互聯網上找到大量資源。

2

我的意見是我永遠不會將錯誤靜音。

如果引發了一些異常,應將其視爲致命錯誤。

也許問題是拋出異常的東西不是例外。例如,業務驗證不應該拋出這樣的例外。

我更願意驗證業務並將錯誤轉化爲「破損的規則」並將它們傳輸到演示文稿或任何地方,這樣可以節省CPU和內存,因爲沒有堆棧跟蹤。

另一種情況是數據連接丟失或使應用程序處於錯誤狀態的其他情況。然後,我寧願記錄錯誤並提示用戶重新打開應用程序,或者應用程序可能會重新啓動。

我想給你一些建議:你有沒有聽說過PostSharp?檢查它,你可以用AOP範例實現這個異常記錄。

0

取決於您希望自己的應用做什麼...... 例如,如果在嘗試連接到數據庫時遇到SqlException,則顯示一條友好的消息「無法登錄」即可。

處理所有錯誤有時被認爲是不好的,儘管人們會不同意... 您的應用程序遇到了您沒有預料到的異常,您不能再100%確定您的應用程序處於何種狀態,執行了哪些代碼行哪些沒有,等等。關於此的進一步閱讀:http://blogs.msdn.com/b/larryosterman/archive/2005/05/31/423507.aspx。 更多信息:http://blogs.msdn.com/b/oldnewthing/archive/2011/01/20/10117963.aspx

0

try/catch的要點是允許您捕捉並處理優雅莊園中的錯誤,允許應用程序繼續執行,而不是簡單地使應用程序崩潰並停止執行。

因此,返回默認值是完全可以接受的。但是,如果返回默認值而不是導致更多錯誤,請確保以下所有代碼都能繼續運行。

例如 - 在您的示例中,如果數據庫連接失敗,請確保沒有其他命令可以從數據庫編輯/檢索值。

4

我不認爲這是一個好的解決方案。在我看來,讓調用者處理異常會更好。或者,您可以捕獲該方法中的異常並拋出一個自定義異常(捕獲異常作爲內部異常)。

的繞了會做一個TryGet方法,如另一種方式:

public static bool TryGetNameById(int id, out string name) 
{ 
    try 
    { 
     //Connect to Db and get name - some error occured 
     name = actualName 
     return true; 
    } 
    catch(Exception ex) 
    { 
     Log(ex); 
     name = String.Empty; 
     return false; 
    } 
} 

我覺得這個方法是比較用心暴露。方法名稱本身表明它不一定能夠產生有用的結果。在我看來,這比返回調用者必須能夠知道做出正確業務邏輯的默認值要好。

0

這真的取決於。在大多數情況下,它不是 - 問題我,如果有一個情景特定的問題,你艾米從來沒有發現。 Soemtiems恢復嘗試很好。這normalyl取決於情況和實際的邏輯。

其中「燕子和文件」的場景是真的有效的是罕見的,在正常的世界之間遠遠英寸在編寫驅動程序類型的時候,它們會更頻繁地出現(如加載的模塊對外部系統)。返回值還是默認(T)等價maeks意義也取決於。

我會說的99%的情況讓例外跑起來。在1%的情況下,返回一些合理的默認值是合理的。

0

我認爲答案必須是「取決於」。

在某些情況下可能是可接受的從一個函數在發生錯誤的情況下返回一個空字符串。如果你正在查找某個人的地址來顯示,那麼一個空的字符串工作正常,而不是崩潰整個事情。

在其他情況下,它可能不那麼有效。如果您正在返回一個字符串,用於例如安全查詢(如getSecurityGroup),那麼你會如果返回錯誤的事情有非常不希望的行爲,你可能會更好保持拋出的錯誤,讓用戶知道有些事情出了錯,而不是假裝別的。如果你堅持由用戶提供給您的數據

更糟糕的是可能。當你得到他們的數據時,出現了一些錯誤,你會返回一個默認和存儲,甚至沒有告訴他們......這一定很糟糕。

所以我認爲你需要看看每個方法,你正在考慮這一點,並決定是否有道理拋出異常或返回默認值。

事實上,作爲一個更一般的規則,每當你發現一個錯誤時,你應該認真思考它是一個可接受的錯誤,並且繼續是允許的,或者它是一個停止顯示的錯誤,你應該放棄。