date: 2009.01.04
一,概述
創造可信賴的,健壯的軟體並不是一件不可能的事情。大部分的商業軟體,在長時間可以無重大故障的工作,但它們並非沒有任何的錯誤,只是擁有低出錯率,你可以迅速理解出錯原因然後快速搞定它,並且,它不會因為外部錯誤而毀壞資料。軟體中有錯誤是可以原諒的,甚至是可以預料到的;不可原諒的是無法解決乙個**的錯誤,僅僅是因為沒用足夠的資訊
二,合理使用.net異常處理機制
1,不要丟擲new exception()
exception
是乙個非常大的類,如果沒有
side-effect(
***),很難去捕獲。引用你自己的異常類,但是使它繼承自
。通過這種方法,你可以設計乙個專門的異常捕獲程式去捕獲框架丟擲的異常,同時設計另乙個異常捕獲程式來處理自己丟擲的異常。
2,每個執行緒要有單獨的catch (exception ex)語句
在你的應用程式中,普通的異常處理應該被集中解決。每個執行緒需要乙個單獨的
try/catch
模組,否則,你將會丟失異常導致非常難處理的問題的出現。當乙個應用程式啟動若干執行緒去做一些後台處理時,通常你需要建立乙個用來儲存處理結果的類。不要忘記新增用來儲存可能發生的異常的區域,否則在主線程中你將無法與之通訊。
3,要記錄exception的全部資訊
在捕獲錯誤以後,應該記錄的是
exception.tostring()
,而不僅是
exception.message
。exception.tostring()
將會給你乙個堆疊跟蹤內部的異常和資訊。通常,這個資訊是及其珍貴的,如果你僅記錄
exception.message
,你將會僅僅獲得一些沒用的資訊。
4,要有清理**
不要忽略的一件事是
try/finally
模組如何使你的**變得更加可讀與健壯,這是處理**的巨大作用所在。
舉個例子,假設你需要從乙個臨時檔案中閱讀一些臨時資訊,然後以字串的形式返回它。不管發生什麼,你都必須刪除這一檔案。這樣的返回處理功能需要
try/finally
模組來完成。
tryfile.delete(filename);
return filecontents;
}catch (exception ex)
finally
5,經常使用using
乙個物件上呼叫
dispose()
函式是遠遠不夠的。關鍵字
using
將會阻止資源洩漏即使在有異常出現的地方。從上面的例子我們也可以看到這個好處。
6,當再次丟擲異常時不要清空堆疊追蹤
堆疊追蹤是乙個異常攜帶的最有用的資訊之一。經常,我們需要在
catch
模組中,放入一些異常處理**(如,回滾乙個事務)然後再丟擲異常。但很多人會犯下以下的錯誤:
trycatch (exception ex)
為什麼這個是錯誤的呢?因為,當你檢查堆疊跟蹤時,異常將會執行到「throw ex」這一行,隱藏了真實的出錯位置。你可以試一下。
trycatch (exception ex)
觀察以上**什麼改變了呢?取代了這個將會拋出新異常同時清空堆疊追蹤的
「throw ex;」
語句,我們使用了簡單的
「throw;」
語句。如果你沒有指定這個異常,
throw
宣告將會僅僅再次丟擲
catch
宣告捕獲的異常。這將會保證你的堆疊追蹤完整無缺,但是依然允許你在
catch
模組中放入**
三,全域性錯誤捕獲
儘管你已經在極大部分的**裡面加入
try{}catch{}
錯誤捕獲語句,但依然無法肯定你的**不會有未捕獲的錯誤。允許未捕獲錯誤的發生,會直接讓程式非法操作,並且無法獲取該錯誤的詳細資訊。
全域性錯誤
的捕獲能
幫你解決這個問題。首先,我們先建立乙個使用者錯誤處理類:
//////
使用者錯誤處理類
///public
static
class
userexception
//////
全域性錯誤處理函式
///public
static
void
doexception(
exception
ex)}
然後在應用程式
program
類中,新增事件委託:
//委託錯誤處理事件
.threadexception +=
newsystem.threading.
threadexceptioneventhandler
(userexception
.threadexception);
事實上,錯誤捕獲以後,應用程式應該關閉,而不應該繼續執行。但是新增全域性錯誤捕獲以後,可以記錄下未知錯誤的詳細資訊,甚至做更多的事情,例如:錯誤傳送。
四,應用程式域級別的錯誤捕獲
事實上,
不是萬能的,最重要的一點,它不能捕獲執行緒級的錯誤。
這裡介紹另外一種錯誤捕獲
方法,它是基於應用程式域(一種邊界,它由公共語言執行庫圍繞同一應用程式範圍內建立的物件建立。應用程式域有助於將在乙個應用程式中建立的物件與在其他應用程式中建立的物件隔離,以使執行時行為可以預知。在乙個單獨的程序中可以存在多個應用程式域。)級別的。
然而必須告訴你的是,這個方法並不建議用於捕獲執行緒級的錯誤。理由有很多,其中乙個是,此方法捕獲錯誤後,程式必須退出,因此無法實現某些中斷執行緒而主程序繼續允許的需求。
同樣我們需要建立乙個應用程式錯誤處理類:
//////
應用程式錯誤處理類
///public
static
class
}然後在應用程式
program
類中,新增事件委託:
//委託錯誤處理事件
.currentdomain.unhandledexception +=
newunhandledexceptioneventhandler
(.domainunhandledexception);
必須記住的是,捕獲應用程式域的錯誤以後,程式必須用語句關閉,否則程式依然會發生恐怖非法操作。
五,執行緒級的錯誤捕獲
你會發現,開了多執行緒的程式,發生錯誤的機率會大大增加。但是有時候,並不能因為某個執行緒發生了錯誤,而必須終止程序。另外,執行緒中
try…catch
以後,如果和主程序互動,都是個困難的問題。
不管出於怎樣的考慮,都建議把每個執行緒中捕獲的錯誤,放到乙個專門的類中去處理。如果需要與主程序互動,這個類還應該有委託函式,把處理交給主程序。
//////
執行緒錯誤處理類
///public
class
workerthreadexception
public
workerthreadexception(
exception
ex)///
///工作執行緒錯誤捕獲委託
///public
delegate
void
workerthreadexceptionhandlerdelegate
(exception
ex);
//////
工作執行緒錯誤捕獲處理函式
///public
void
workerthreadexceptionhandler(
exception
ex)}
可以看到,該類把捕獲到的錯誤,引發到
中,統一處理。當然,你可以做更多的事情。下面,我們建立乙個執行緒:
private
void
button_click(
object
sender,
eventargs
e)private
void
testerror()
catch
(exception
ex)}
可以看到,執行緒中
catch
到錯誤後,建立了
workerthreadexception
總結
發生錯誤並不可怕;可怕的是,錯誤重**生,而你卻對它一無所知。
04 異常處理規範
異常處理類似程式的預警機制,當程式出現了異常狀態時,開發者可以使用已經設計好的異常處理 將異常排除,確保程式穩定執行。但如果異常處理使用不當,不僅不會解決問題,還會嚴重影響程式的執行效率。本節將介紹一些基本的異常處理規範。catch語句的大括號內必須有異常處理語句,不要不寫任何 反例 trycatc...
springboot異常處理的基本規範
springboot解決跨域問題的兩種方案 1 通過給方法或者類加註解的形式,crossorigin。第一種方式 指定請求 可以寫成 表示接收所有 的請求。第二種方式 configuration public class webmvcconfig implements webmvcconfigure...
規範響應格式以及統一異常處理
我認為,採用預先約定好的資料格式,將返回資料 無論是正常的還是異常的 規範起來,有助於提高團隊間介面對接的效率 前端和後端,後端和後端等 思路 實現 1.建立errorresult類 public class errorresult implements serializable 2.建立restr...