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
Dim i
i = 1/0 '第一個錯誤
undefined_function "test" '第二個錯誤,函數undefined_function未定義
Response.Write Err.Description
運行結果:
類型不匹配
可以看到,提示的並不是被零除
使用On Error Goto 0 語句,讓系統重新接管錯誤的處理
加上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語句,那么就跳向外層。這個過程一直重復,直到找到包含有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語句,出現的運行期錯誤不會中止這個子程序的運行,。
例如,如果需要向一個文件中寫入字符串,可以通過一個獨立的函數對文件進行訪問,防止錯誤中斷整個程序的運行:
'and writes strContent into it then closes the file
'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 bjFSO = CreateObject("scripting.FileSystemObject")
If Err.Number = 0 Then Set bjFile = 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,以確定所選擇的錯誤號不會和一個已存在的錯誤號混淆。通過把任意選擇的錯誤號加到此常數中,就能夠保證和預定義的錯誤不混淆。
On Error Resume Next
ReadThisFile = "" 'default return value of function
Set bjFSO = CreateObject("scripting.FileSystemObject")
Set bjFile = 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