介紹完了On Error 敘述后,相信大家對于錯誤處理的方式及流程應該有基礎的認識了。接著我們要來介紹.NET 架構里最新的錯誤處理方式Try...Catch。我們前面提到On Error 雖然簡單但是不夠結構化,因此.NET 便加入了Try...Catch 的除錯方式,使我們能夠更有效率的撰寫錯誤處理法則。
例外(Exception)
錯誤被稱為例外(Exception),而例外也是對象;它和Err 對象不一樣,不同的例外被做成不同的對象。例如將非數值型態的數據以型態轉換函數處理時,會發生FormatException 型態的例外;而提供這個例外信息的是FormatException 對象。
Try...Catch
Try...Catch 的概念基本上和On Error 敘述一樣,它也是當發生錯誤時就跳到例外處理程序中,其結構如下所示:
Try
程序執行的區塊
Catch 變量As 例外對象
例外處理程序的區塊
End Try
我們可以針對不同的例外來建構不同的例外處理程序,例如:
Try
程序代碼
Catch 變量As 例外對象
例外處理程序代碼
Catch 變量As 例外對象
例外處理程序代碼
[Finally]
例外處理程序代碼
End Try
下列范例將On Error 錯誤捕捉改成Try...Catch 處理,我們一樣只要輸入非數值型態的內容至TextBox 中即可引法錯誤:
<Html>
<Form Runat="Server">
<ASP:TextBox Id="Text1" Runat="Server"/>X
<ASP:TextBox Id="Text2" Runat="Server"/>
<ASP:Button Id="Button1" Text="=" OnClick="Button1_Click"
Runat="Server"/>
<ASP:Label Id="Label1" Runat="Server"/><p>
<ASP:Label Id="Label2" Runat="Server"/>
</Form>
<Script Language="VB" Runat="Server">
Sub Page_Load(Sender As Object,e As Eventargs)
Label1.Text=""
Label2.Text=""
End Sub
Sub Button1_Click(Sender As Object,e As EventArgs)
Try
Label1.Text=CInt(Text1.Text)/Cint(Text2.Text)
Catch ex as FormatException
Label2.Text="兩邊都必須輸入數字"
End Try
End Sub
</Script>
</Html>
由于將非數值型態的內容傳入CInt 函數中態引發了FormatException 類型的錯誤,因此就跳到Catch 區塊來處理例外。由于例外對象全部都是從Exception 對象繼承下來的,因此在使用多個Catch 時要注意順序。例如下面程序代碼片段,我們若把Exception 類別的對象放在FormatException 類別對象之前,則偵測FormatException 類型的例外處理將不會被執行:
Try
引發例外的程序代碼
Catch err1 As Exception
例外處理的程序代碼
Catch err2 As FormatException
例外處理的程序代碼
End Try
Finally
Finally 區塊不管有沒有發生例外都會執行,我們可以使用Finally 區塊來做一些最后的處理。下列范例當我們按下Button1 程序執行到Try 區塊,無論例外有無發生都會執行Finally 區塊的中的程序代碼:
<Html>
<Form Runat="Server">
<ASP:TextBox Id="Text1" Runat="Server"/>X
<ASP:TextBox Id="Text2" Runat="Server"/>
<ASP:Button Id="Button1" Text="=" OnClick="Button1_Click"
Runat="Server"/>
<ASP:Label Id="Label1" Runat="Server"/><p>
</Form>
<Script Language="VB" Runat="Server">
Sub Page_Load(Sender As Object,e As Eventargs)
Label1.Text=""
Label2.Text=""
End Sub
Sub Button1_Click(Sender As Object,e As EventArgs)
Try
Response.Write("Try 區塊<Br>")
Label1.Text=Cint(Text1.Text)/Cint(Text2.Text)
Catch ex As FormatException
Response.Write("Catch 區塊<Br>")
Finally
Response.Write("Finally 區塊")
End Try
End Sub
</Script>
</Html>
沒有發生例外時
發生例外時
Throw
在On Error 結構中我們可以使用Err 對象的Raise 方法來自行引發一個例外,而ASP.NET 新的例外處理機制中也提供了Throw 敘述,讓我們引發一個自訂的錯誤敘述;其使用語法如下:
Throw New 例外對象
下列范例中我們自行丟出一個Exception 型別的例外,然后在Catch 區塊中印出Exception 類別對象的例外說明:
<Html>
<Form Runat="Server">
<ASP:Button Id="Button1" Text="產生例外" OnClick="Button1_Click"
Runat="Server" />
</Form>
<Script Language="VB" Runat="Server">
Sub Button1_Click(Sender As Object,e As Eventargs)
Try
Response.Write("自行丟出一個Exception 例外<Br>")
Throw New Exception
Catch ex As Exception
Response.Write(ex.ToString())
End Try
End Sub
</Script>
</Html>
Try....Catch 的結構化使得我們的例外處理變的相當有效率,我們可以在程序代碼中使用Try....Catch 結構來處里我們的例外,不用擔心程序的執行流程被改變。使用Try....Catch 要注意不破壞原有的程序代碼結構,例如下列程序代碼片段是錯誤的示范:
Try
For shtI=0 To 9
Response.Write(shtI)
Catch ex As Exception
...
Next
巢狀的Try...Catch
我們可以在Catch 區塊或Finally 區塊中再使用Try....Catch 敘述,如下列范例所示:
<Html>
<Form Runat="Server">
<ASP:Button Id="Button1" Text="產生例外" OnClick="Button1_Click"
Runat="Server"/>
</Form>
<Script Language="VB" Runat="Server">
Sub Button1_Click(Sender As Object,e As Eventargs)
Try
Response.Write("自行丟出一個Exception 例外<P>")
Throw New Exception
Catch err As Exception
Try
Response.Write(err.ToString() & "<P>")
Response.Write("再產生一個例外<P>")
Throw New IndexOutOfRangeException()
Catch err1 As IndexOutOfRangeException
Response.Write(err1.ToString())
End Try
End Try
End Sub
</Script>
</Html>