使用On Error Resume Next语句,On Error Goto 0语句,Err对象来处理"运行时错误"

VBScript语言提供了两个语句和一个对象来处理"运行时错误",如下所示:

  • On Error Resume Next语句
  • On Error Goto 0语句
  • Err对象

简单介绍一下On Error Resume Next,On Error Goto 0,Err这三者

On Error Resume Next语句和On Error Goto 0语句指明了当出现"运行时错误"时的处理方式。

当加上On Error Resume Next语句后,如果后面的程序出现"运行时错误",会继续运行,不中断。

当加上On Error Goto 0语句后,如果后面的程序出现"运行时错误",会显示"出错信息"并停止程序的执行。

Err对象保存了“错误信息”

下面结合例子讲解On Error Resume Next,On Error Goto 0,Err这三者

没有加上On Error Resume Next语句

如果没有加上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这条语句后,随后的程序即便出现"运行时错误"时,也不会显示"出错信息",并且会继续运行下去.

举例:

On Error Resume Next '后面的程序即便出现"运行时错误"时,也会继续运行
i = 1/0 '0作除数,这是一种"运行时错误",但因为有了上面On Error Resume Next这句话,所以不会中断执行,而是会继续运行下去
Response.Write "除法执行后" '这句话将会执行

结果:

除法执行后

加上On Error Resume Next语句后,使用Err对象来得到错误信息

使用了On Error Resume Next之后,如果出错,那么Err对象中将放置最近一次出错的信息。

Err对象重要的属性有三个:Number, Source, Description,分别是错误号,错误来源,错误描述。

If Err then这样的写法等价于If Err.Number then

举例:

On Error Resume Next
i = 1/0 '第一个错误
undefined_function "test" '第二个错误,函数undefined_function未定义
Response.Write Err.Description

运行结果:

类型不匹配

可以看到,显示的是有关第二个错误的信息。

详细讲一下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语句,则会接着执行“子程序调用”之后的语句。如果外层程序在“调用这个子程序之前”没有On Error Resume Next语句,那么就跳向更外一层。

这个过程一直重复,直到找到包含有On Error Resume Next语句的环境继续运行,如果最外层的程序也没有包含On Error Resume Next语句,那么将会使用缺省的错误处理方式,也就是显示错误信息并停止运行。

下面通过3个例子来了解两个知识点。

  • On Error Resume Next语句的作用范围。
  • 子程序中如果没有On Error Resume Next语句,并且出现了"运行时错误",是如何向外层程序跳转的

例子1:

On Error Resume Next
level_1 '本语句前有On Error Resume Next,因此level_1退出时,会继续向下执行
Response.Write "<p>level_1调用后</p>"

Sub level_1()
 level_2 '本语句前没有On Error Resume Next,因此level_2退出到本子程序时,不会继续向下执行,而是接着向外层程序跳转
 Response.Write "<p>level_2调用后</p>"
End Sub

Sub level_2()
 i = 1/0 '本语句前没有On Error Resume Next,因此执行到此时,会中断本子程序的运行,跳转到外层程序
 Response.Write "OK"
End Sub

结果:

level_1调用后

两个子程序中的Response.Write语句都没有执行。

解释:

  • 上面的程序中,在全局性范围内调用了子程序level_1,而level_1又调用了子程序level_2,因此程序按照“调用关系”形成了3个层次。
  • On Error Resume Next处于最外层,因此它不会影响到被调用的子程序。而子程序中没有On Error Resume Next,所以当子程序中出了错误后,会直接从子程序中跳出,跳到外层的代码中。
  • 具体来说:

    level_2是最内层的程序,因为i = 1/0语句前没有On Error Resume Next,所以执行到此时,会中断level_2这个子程序的运行,跳转到它的外层程序,也就是level_1子程序

    但level_1子程序在调用level_2子程序之前,同样没有加On Error Resume Next,因此接着跳往外层程序,也就是"全局性程序".

    "全局性程序"在调用level_1子程序之前,加了On Error Resume Next,因此会接着执行"level_1调用语句后面"的语句.

例子2:

改变一下上面的程序,在level_1子程序中的"level_2子程序调用语句"前加上On Error Resume Next

level_1
Response.Write "<p>level_1调用后</p>"

Sub level_1()
 On Error Resume Next
 level_2 '本语句前有On Error Resume Next,因此level_2退出到本子程序时,会继续执行下面的语句
 Response.Write "<p>level_2调用后</p>"
End Sub

Sub level_2()
 i = 1/0 '本语句前没有On Error Resume Next,因此执行到此时,会中断本子程序的运行,跳转到外层程序
 Response.Write "OK"
End Sub

结果:

level_2调用后

level_1调用后

解释:

  • level_1子程序中有On Error Resume Next,但这句话不会影响到调用的level_2子程序.因此,在level_2子程序运行时,遇到"运行时错误"仍然会中断运行,向外跳转
  • 因为调用level_2子程序前加上了On Error Resume Next,所以当从level_2子程序退出到level_1子程序时,会接着执行"子程序调用语句后面"的语句

例子3:

改变一下上面的程序,在level_2子程序中的"i = 1/0"语句前加上On Error Resume Next

level_1
Response.Write "<p>level_1调用后</p>"

Sub level_1()
 level_2
 Response.Write "<p>level_2调用后</p>"
End Sub

Sub level_2()
 On Error Resume Next
 i = 1/0 '本语句前有On Error Resume Next,因此即便本语句有错误,也不会中断执行,而是会继续执行下面的语句
 Response.Write " <p>i = 1/0 执行后</p>"
End Sub

结果:

i = 1/0 执行后

level_2调用后

level_1调用后

通过例子3可以看到,如果在子程序的开头放置一条On Error Resume Next语句,那么子程序中出现的运行期错误不会中止这个子程序的运行,即使自身出现错误也不会影响到外层程序。

这种方法通俗的讲就是:自己内部的错误,自己解决,不让它扩散出去。

因此编程时,推荐采用这种方法.

下面举个例子。有一个名为WriteNewFile的函数,功能是:向一个文件中写入字符串.函数内部会对可能出现的错误进行处理,这样以来,错误就不会中断调用程序的运行:

'函数功能:创建一个名为strFileName的文件, 并且将字符串strContent写入文件
'如果函数执行成功,则返回值是true, 只要有错误发生,则返回值就是false
Function WriteNewFile(strFileName, strContent)
 On Error Resume Next '关闭默认的错误处理器
 WriteNewFile = Flase '函数默认的返回值
 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”。

加上On Error Resume Next语句后,后面的程序即便出现"运行时错误"时,也会继续运行.可是如果希望后面的程序出现"运行时错误"时停止执行并显示错误,该怎么做呢?

答案是:使用On Error Goto 0 语句

使用On Error Goto 0 语句,让系统重新接管错误的处理

在运行这个语句后,如果发生运行时错误,将采用缺省的处理方式,也就是,在调用链中逐步向外跳转,直到主页面代码,如果没有环境关闭缺省错误处理,那么网页的执行将停止并显示错误信息。

使用 On Error Goto 0 这条语句后,后面的程序一旦有错误发生就会提示错误,并结束脚本执行。

举例:

On Error Resume Next
Dim i
i = 1/0
Response.Write "第一个除法执行后"
On Error Goto 0 '后面的语句一旦有错误发生就会提示错误,并结束脚本执行
i = 1/0
Response.Write "第二个除法执行后"

运行结果:

第一个除法执行后

Microsoft VBScript 运行时错误 错误 '800a000b'

被零除

/test.asp,行 7

可以看到,第一个Response.Write执行并输出了内容,第二个Response.Write没有执行。

Err对象

Err对象存储了关于运行期错误的信息

下表给出了Err对象的属性。

Err对象的属性功能说明
Description对于错误的详细描述
Number错误编号,唯一性的标识一类错误.两种不同类型的错误,编号不同.(缺省属性)
Source产生错误的对象的名称

使用Number属性值可以检查发生了哪种错误,使用Source和Description属性值得到错误的具体信息。

下表给出了Err对象的方法。

Err对象的方法功能说明
Clear清除当前所有的Err对象设置
Raise产生一个运行时错误

使用Err对象生成一个“自定义错误”。

所谓“自定义错误”就是这个错误的Number, Source, Description三个属性可以由编程人员设定.

生成“自定义错误”的方法:首先把Err对象的Number, Source, Description三个属性设置成所希望的值,然后调用Raise方法来产生这种错误.

“自定义错误”和“普通错误”一样,会停止本级程序的运行,把错误沿调用链向回传递。

下面的例子中,函数Read_File会读取一个文本文件,如果出现自定义的错误,就向外层程序抛出,由外层程序决定如何处理错误。

注意常数vbObjectError的用法。把任意一个数字加到此常数上,就能够保证“自定义错误”的编号(number值)不会和任何“已定义错误”的编号重合。

Function Read_File(strFileName) '返回文件内容
 On Error Resume Next
 Read_File = "" '函数默认的返回值
 Set objFSO = CreateObject("scripting.FileSystemObject")
 Set objFile = objFSO.OpenTextFile("strFileName", ForReading)
 Select Case Err.Number
  Case 0 '没错误, 不做任何动作
  Case 50,53 '文件或者路径不存在
   '下面将会创建一个“自定义错误”,并且向外层程序抛出这个错误
   intErrNumber = vbObjectError + 1073 '“自定义错误”的编号
   strErrDescription = "文件被删除了,或是移动到了其他位置"  '对于“错误”具体情况的描述
   strErrSource = "本错误是在Read_File函数中产生的" '表明“错误”的发生地点,也就是在Read_File这个函数中
   Err.Raise intErrNumber, strErrSource, strErrDescription '生成“自定义错误”
   Exit Function
  Case Else '其他类型的错误
   Err.Raise Err.Number, Err.Source, Err.Description  '对于“已定义错误”,保持原貌
   Exit Function
 End Select
 Read_File = objFile.ReadAll '文件打开成功,返回文件的内容
 objFile.Close
End Function

函数Read_File运行时,可能会产生“自定义错误”,因此调用这个函数前加上On Error Resume Next语句,这样就能捕获到这个函数产生的错误,然后作处理。

On Error Resume Next
strContent = Read_File("myfile.txt")
If Err.Number = 0 Then
  Response.Write "文件内容:<br/>" & strContent
Else
  Response.Write "执行Read_File函数时产生错误。" & Err.Source & "<br/>" & Err.Description
End If

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值