介绍完了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>
