VBScript语言提供了两个语句和一个对象来处理"运行时错误",如下所示:
简单介绍一下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这三者
i = 1/0 '0作除数,产生"运行时错误",显示"出错信息"并停止程序的执行
Response.Write "除法执行后" '这句话将不会执行
结果:
Microsoft VBScript 运行时错误 错误 '800a000b'
被零除
/test.asp,行 2
On Error Resume Next '后面的程序即便出现"运行时错误"时,也会继续运行
i = 1/0 '0作除数,这是一种"运行时错误",但因为有了上面On Error Resume Next这句话,所以不会中断执行,而是会继续运行下去
Response.Write "除法执行后" '这句话将会执行
结果:
Microsoft VBScript 运行时错误 错误 '800a000b'
被零除
/test.asp,行 2
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 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语句,那么就跳向外层。这个过程一直重复,直到找到包含有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”。
On Error Goto 0语句
在ASP 2.0(尽管没有文档记录)和ASP 3.0中,On Error Goto 0语句可以恢复缺省的错误处理行为。
在运行这个语句后,发生的运行期错误将导致缺省错误处理,在环境链中检查每个嵌套的程序,直到主页面代码。如果没有其他的环境关闭缺省错误处理,网页的执行将停止并显示IIS缺省错误网页。
Err对象
在前面的例子中,关闭缺省错误处理后,通过检查Err对象的Number属性,查看错误是否已经出现。
Err对象存储了关于运行期错误的信息
下表给出了Err对象提供的属性。
Description | 设置或返回一个描述错误的字符串 |
Number | (缺省属性)设置或返回指定一个错误的值 |
Source | 设置或返回产生错误的对象的名称 |
使用这些属性可以检查发生了哪种错误。例如,可以根据错误号采取不同的措施,也可以用Source和Description的属性值为用户提供错误信息。
下表给出了Err对象提供的方法。
Clear | 清除当前所有的Err对象设置 |
Raise | 产生一个运行期错误 |
使用Err对象生成一个“自定义错误”。
可以使用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:<br/>" & strContent
Else
Response.Write Err.Source & "<br/>" & Err.Description
End If
下面是另一篇:
用了on error resume next
则在这句往后的代码就算出错也会继续执行
具体有没有错可以用err.number来判断
err.number=0表示没有出错
err.number<>0表示有错
具体什么错误可以用ASPError对象获得
首先建立
set objasperror=server.GetLastError 对象,接着由 ASPError 物件的属生取得相关信息:
objasperror.ASPCode | 传回iis产生的错误码 |
objasperror.Number | 传回com标准错误码,如 0x800a03fc |
objasperror.Source | 传回实际产生错误的原始码 |
objasperror.Category | 指出错误的来源为 asp、script 或是 object |
objasperror.File | 传回错误程序档案名称 |
objasperror.Line | 传回错误程序的行数 |
objasperror.Column | 传回错误程序的列数 |
objasperror.Description | 传回错误原因简介 |
objasperror.ASPDescription | 传回详细错误原因 |
简单介绍
ASP是非常简单的,以至于许多的开发者不会去思考错误处理。错误处理能够让你的应用程序更加合理。我看到过很多个用ASP编写的商业网站,大多数都忽略了错误处理。 错误的类型
有三种主要的错误类型:
1.编译错误:
这种错误出现一般都是代码的语法问题。因为编译错误而导致辞ASP停止运行。
2.运行错误:
这个错误是发生在你准备运行ASP时的。例如:如果你试图给一个变量赋值,但是却超出了该变量允许的范围。
3.逻辑错误:
逻辑错误是最难被发现的,这种错误经常是一种结构错误,电脑是发现不了的。这就需要我们彻头彻尾地检查我们的代码。
因为编译错误一般是和逻辑错误一起发生的,一般都能显示出来,所以我们担心的就只是运行错误。它都终止ASP的运行,而且给用户丢下一堆很不友好的文字。 那么我们要怎样处理运行错误呢?
我们先来看看,ASP唯一提供给我们的错误命令—On Error Resume Next(这里提醒一下初学者,在ASP中只有On Error Resume Next语句,没有On Error Resume Goto语句) 如果你不使用On Error Resume Next语句的话,一切运行错误都会发生,这个是致命的,那么就会有一段错误代码“展现”给用户,而且ASP程序也会停止。 下面就是一个错误代码:
Microsoft OLE DB Provider for ODBC Drivers error 80004005 [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified /test.asp, line 60
当我们在程序最上面使用On Error Resume Next语句时,所有的错误都会被忽略,程序会自动执行下一条语句。这样程序就会完全执行,出错后用户也不会看到出错信息。但是这样也有 不好的地方,那就是如果程序没有按照你想像的执行的话,你就很难找到到底是哪里出了问题,所以你就得在必要的地方对错误进行处理。
处理错误
在ASP中,处理错误的最好的办法就是在程序最底端放上代码来处理错误。我也推荐在每个ASP程序都使用缓冲区。这样的话,如果错误发生,页面就会停止, 页面内容也会被清除,这样用户就不会看到错误信息,对你们的抱怨也就少了!下面是一个例子:
<%@ LANGUAGE="VBScript" %>
<%Response.Buffer = True
"设置buffer为True
On Error Resume Next
"开始错误处理
%>
<%"错误处理
If Err.Number <> 0 Then
"清除页面
Response.Clear
"显示错误信息给用户
%>
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY BGCOLOR="#C0C0C0">
<FONT FACE="ARIAL">An error occurred in the execution of this ASP page<BR>
Please report the following information to the support desk
<P><B>Page Error Object</B><BR>
错误 Number: <%= Err.Number %><BR>
错误信息: <%= Err.Description %><BR>
出错文件: <%= Err.Source %><BR>
出错行: <%= Err.Line %><BR>
</FONT>
</BODY>
</HTML>
<%End If%>
你们上面看到了,我首先设置On Error Resume Next ,这样出现错误就不会影响程序的执行。
错误处理和数据库
在错误处理中加入数据库的执行是很复杂的。假若我们有一个程序,有很多的命令去向数据库中添加记录,如果insert/update在程序的最底部执行,如果我们前面又错误发生,那就完了!我们就会向数据库中添加了一个错误的信息。因为我们用了On Error Resume Next 一切的错误都被忽略了!即使前面出错,程序依旧会向数据库中添加数据的。
为避免这种情况,我们就先得做些手脚,正确处理的方法如下:
If Err.Number = 0 And objConnection.Errors.Count = 0 Then
"这里才能执行语句,因为没有错误
Set rstResults = dbData.Execute(txtSql)
End If
更多高级的处理办法
当一个错误发生时,你们也可以显示更多的错误信息。下面是同时处理数据库和页面错误的例子,有了它我们一下就能发现我们程序中的所有错误。 (由于有些地方我觉得英文更能说时问题,所以没有翻译)。
<% If Err.Number <> 0 Then
Response.Clear
Select Case Err.Number
Case 8
"指定错误的Number
"在这里处理自定义错误
Case Else
"一般错误
If IsObject(objConnection) Then
If objConnection.Errors.Count > 0 Then
%>
<B>Database Connection Object</B>
<%
For intLoop = 0 To objConnection.Errors.Count - 1 %>
Error No: <%= objConnection.Errors(intLoop).Number %><br>
Description: <%= objConnection.Errors(intLoop).Description %><BR>
Source: <%= objConnection.Errors(intLoop).Source %><BR>
SQLState: <%= objConnection.Errors(intLoop).SQLState %><BR>
NativeError: <%= objConnection.Errors(intLoop).NativeError %><P>
<% Next
End If
End If
If Err.Number <> 0 Then %> <B>
Page Error Object</B><BR>
Error Number <%= Err.Number %><BR>
Error Description <%= Err.Description %><BR>
Source <%= Err.Source %><BR>
LineNumber <%= Err.Line %><P>
<%End If
End Select
End If %>
上面的例子让我们一下了处理了很多在数据库中出现的问题,这个在我们日常编程也是常用的!我们也应该看到那个Select Case 语句,它能让我们来处理特定的错误。
Redirect 和错误处理
有一点我们就当注意一下,就是我们常用到的redirect对象,如果一个页面中出现了redirect对象,那么错误处理就失去了意义。所以在转向之前我们还得处理一下,如下:
If Err.Number = 0 And objConnection.Errors.Count = 0 Then
Response.Clear
Response.Redirect ?lt;URL Here>?
End If
把代码变得更整齐
为了让代码变得更整齐,首先把错误处理的文件放在一个包含文件中。这样你就可以在任何文件中使用它。这样修改也方便。在你程序的最上方加入(当然在语言声明之后)On Error Resume Next语句。在你执行SQL以前进行错误检查。使用redirect以前也要进行错误处理。
让你处理错误的包含文件在代码的最上面