VBScript语言提供了两个语句和一个对象来处理"运行时错误",如下所示:
On Error Resume Next语句和On Error Goto 0语句指明了当出现"运行时错误"时的处理方式。
当加上On Error Resume Next语句后,如果后面的程序出现"运行时错误"时,会继续运行,不中断。
当加上On Error Goto 0语句后,如果后面的程序出现"运行时错误"时,会显示"出错信息"并停止程序的执行。
Err对象保存了“错误信息”
如果没有加上On Error Resume Next语句,当出现"运行时错误"时,会显示"出错信息"并停止程序的执行.
举例(/test.asp文件):
i = 1/0 '0作除数,产生"运行时错误",显示"出错信息"并停止程序的执行 Response.Write "除法执行后" '这句话将不会执行 %>
结果:
Microsoft VBScript 运行时错误 错误 '800a000b'
被零除
/test.asp,行 2
当我们在某处加上On Error Resume Next这条语句后,随后的程序即便出现"运行时错误"时,也不会显示"出错信息",并且会继续运行下去.
举例:
On Error Resume Next '后面的程序即便出现"运行时错误"时,也会继续运行 i = 1/0 '0作除数,这是一种"运行时错误",但因为有了上面On Error Resume Next这句话,所以不会中断执行,而是会继续运行下去 Response.Write "除法执行后" '这句话将会执行 %>
结果:
使用了On Error Resume Next之后,如果出错,那么Err对象中将放置最近一次出错的信息。
Err对象重要的属性有三个:Number, Source, Description。分别是错误号,错误来源,错误描述。
你能捕获的都是运行时错误,而且If Err then这样的写法等价于If Err.Number then
Dim i i = 1/0 '第一个错误 undefined_function "test" '第二个错误,函数undefined_function未定义 Response.Write Err.Description
运行结果:
可以看到,提示的并不是被零除
加上On Error Resume Next语句后,后面的程序即便出现"运行时错误"时,也会继续运行.可是如果希望后面的程序出现"运行时错误"时停止执行并显示错误,该怎么做呢?
答案是:使用On Error Goto 0 语句
使用 On Error Goto 0 这条语句后,后面的程序一旦有错误发生就会提示错误,并结束脚本执行。
Dim i i = 1/0 Response.Write "第一个除法执行后" On Error Goto 0 '后面的语句一旦有错误发生就会提示错误,并结束脚本执行 i = 1/0 Response.Write "第二个除法执行后"
运行结果:
Microsoft VBScript 运行时错误 错误 '800a000b'
被零除
/test.asp,行 2
可以看到,第一个Response.Write执行并输出了内容,第二个Response.Write没有执行。
On Error Resume Next语句只作用于本级别的后续语句。不会作用于被调用的函数或子程序,同样也不会作用于父级别的程序段
On Error Resume Next语句如果出现在某个函数中,则只对本函数产生影响。对“主调函数”和“被调函数”均没有影响
一个子程序中如果没有On Error Resume Next语句,那么当错误在子程序中出现时,将会中断这个子程序的运行,跳转到调用这个子程序的外层程序.如果这个外层程序在“出问题的函数调用”之前包含有On Error Resume Next语句,则会接着执行“函数调用”之后的语句。如果这个外层程序在“出问题的函数调用”之前没有On Error Resume Next语句,那么就跳向外层。这个过程一直重复,直到找到包含有On Error Resume Next语句的环境继续运行,如果最外层的程序也没有包含On Error Resume Next语句,那么将会使用缺省的错误处理器,也就是显示错误信息并停止运行。
举例:
Dim i i = 1/0 Response.Write "OK" End Sub Sub test1() test Response.Write "OK" End Sub On Error Resume Next test1
结果:
两个ok都没有被打印。因为On Error Resume Next是在最外层下达的,所以当调用的子程序中出了问题之后,会直接从子程序中跳出,跳到外层的代码中。
如果在子程序的开头放置一个On Error Resume Next语句,出现的运行期错误不会中止这个子程序的运行,。
例如,如果需要向一个文件中写入字符串,可以通过一个独立的函数对文件进行访问,防止错误中断整个程序的运行:
'returns True if it succeeds, or False on any error Function WriteNewFile(strFileName, strContent) On Error Resume Next 'turn off the default error handler WiteNewFile = Flase 'default return value of function Set objFSO = CreateObject("scripting.FileSystemObject") If Err.Number = 0 Then Set objFile = objFSO.CreateTextFile(strFileName,True) If Err.Number = 0 Then objFile.WriteLine strContent If Err.Number = 0 Then objFile.Close If Err.Number = 0 Then WriteNewFile = True End Function
上面的程序在处理每个程序语句之前,先检查Err对象的Number属性。如果值为0(还没有出现错误),那么就能够继续对文件的创建和写入过程。如果错误发生了,脚本引擎将设置Err对象的属性的值,并且继续处理下一行。
只要不引起错误而能正常运行,函数的返回值将设置为“True”。否则函数将返回“False”。
在ASP 2.0(尽管没有文档记录)和ASP 3.0中,On Error Goto 0语句可以恢复缺省的错误处理行为。
在运行这个语句后,发生的运行期错误将导致缺省错误处理,在环境链中检查每个嵌套的程序,直到主页面代码。如果没有其他的环境关闭缺省错误处理,网页的执行将停止并显示IIS缺省错误网页。
在前面的例子中,关闭缺省错误处理后,通过检查Err对象的Number属性,查看错误是否已经出现。
Err对象存储了关于运行期错误的信息
下表给出了Err对象提供的属性。
Description | 设置或返回一个描述错误的字符串 |
Number | (缺省属性)设置或返回指定一个错误的值 |
Source | 设置或返回产生错误的对象的名称 |
下表给出了Err对象提供的方法。
Clear | 清除当前所有的Err对象设置 |
Raise | 产生一个运行期错误 |
可以使用Err对象生成一个“自定义错误”。为什么要做这些呢?因为有时想把一个定制的错误消息传送给用户。可以把Err对象的属性设置成所希望的任何值,然后调用Raise方法来产生这种错误,这样做会停止程序的运行,并且把错误沿调用链向回传递。
下面的例子显示了在服务器磁盘上读取一个文本文件时,如何处理错误。注意如何使用常数vbObjectError,以确定所选择的错误号不会和一个已存在的错误号混淆。通过把任意选择的错误号加到此常数中,就能够保证和预定义的错误不混淆。
Set objFSO = CreateObject("scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile("strFileName", ForReading) Select Case Err.Number Case 0 'OK, take no action Case 50,53 'standard file or path not found errors 'create custom error values and raise error back up the call chain intErrNumber = vbObjectError + 1073 'custom error number strErrDescription = "The file has been deleted or moved. " strErrSource = " ReadThisFile function" Err.Raise intErrNumber, strErrSource, strErrDescription Exit Function Case Else 'som other error 'raise the standard error back up the call chain Err.Raise Err.Number, Err.Source, Err.Description Exit Function End Select ReadThisFile = objFile.ReadAll ' we opened it OK, so return the content objFile.Close End Function
调用这个函数的代码可以使用On Error Resume Next语句,并且能捕获这个函数产生的错误。
strContent = ReadThisFile("myfile.txt") If Err.Number = 0 Then Response.Write "File content is:
" & strContent Else Response.Write Err.Source & "
" & Err.Description End If