首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

VBScript 錯誤處理機制:On Error Resume Next 與 Err 物件完整指南

     編輯:更多程式設計知識

VBScript 不支援現代語言的 try/catch/finally 結構,而是透過 On Error 語句與全域 Err 物件實現錯誤處理。本文系統整理三種 On Error 模式、Err 物件屬性/方法、最佳實踐模式與常見陷阱,幫助維護舊版 ASP、WSH 腳本的開發者寫出健壯代碼。

三種 On Error 模式

語句行為適用場景
On Error Resume Next發生執行錯誤時,**跳過錯誤行**,繼續執行下一行。錯誤資訊存入 Err 物件。預期可能失敗的單行操作(檔案讀寫、COM 物件呼叫、資料庫查詢)。
On Error GoTo 0**關閉**目前程序的錯誤處理,恢復預設行為:發生錯誤即終止腳本並顯示錯誤訊息。在 Resume Next 區塊結束時,恢復嚴格模式。
On Error GoTo <label>跳轉到同一程序內的標籤(label:)。注意:VBScript **不支援**此語法,會編譯錯誤。僅 VB/VBA 支援。不適用於 VBScript。

核心模式:檢查 Err.Number


On Error Resume Next
Dim objFSO, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\nonexist.txt", 1) ' 讀取模式

If Err.Number <> 0 Then
    WScript.Echo "錯誤 " & Err.Number & ": " & Err.Description
    Err.Clear  ' 重要:清除錯誤狀態,避免污染後續判斷
End If
On Error GoTo 0

Err 物件完整屬性與方法

成員型別說明
NumberLong錯誤代碼(0 表示無錯誤)。VBScript 錯誤碼為正數;COM 元件可能回傳負數(如 0x800Axxxx)。
DescriptionString人類可讀的錯誤描述。
SourceString產生錯誤的物件/元件名稱(如 "Microsoft VBScript runtime error")。
HelpFileString說明檔路徑(可自訂)。
HelpContextLong說明檔主題 ID(可自訂)。
Clear()Method重設所有屬性為預設值(Number=0)。
Raise(number, source, description, helpfile, helpcontext)Method主動拋出錯誤,模擬錯誤發生。

進階模式:自訂錯誤與錯誤氣泡


' 定義自訂錯誤碼 (建議用 513 以上避免衝突)
Const ERR_DB_CONN = vbObjectError + 513

Function ConnectDB(connStr)
    On Error Resume Next
    Dim conn
    Set conn = CreateObject("ADODB.Connection")
    conn.Open connStr
    If Err.Number <> 0 Then
        Err.Raise ERR_DB_CONN, "ConnectDB", "資料庫連線失敗: " & Err.Description
    End If
    On Error GoTo 0
    Set ConnectDB = conn
End Function

' 呼叫端
On Error Resume Next
Set db = ConnectDB("Provider=SQLOLEDB;...")
If Err.Number = ERR_DB_CONN Then
    WScript.Echo "自訂錯誤: " & Err.Description
    ' 可選:記錄到事件日誌、發送郵件等
End If
On Error GoTo 0

最佳實踐原則

  1. 最小範圍:僅在預期可能失敗的幾行程式碼前加 On Error Resume Next,隨後立即 On Error GoTo 0。
  2. 必須 Clear:每次處理完錯誤呼叫 Err.Clear,否則 Err.Number 保持非零,導致後續判斷誤以為發生錯誤。
  3. 檢查具體錯誤碼:不要只判斷 Err.Number <> 0,應針對預期錯誤碼處理,其他錯誤向上拋或記錄。
  4. 避免巢狀 Resume Next:內層錯誤會被外層吞沒,極難除錯。若需巢狀,內層用函數封裝並回傳錯誤碼。
  5. 記錄完整資訊:Err.Number & "|" & Err.Source & "|" & Err.Description 寫入日誌檔。

常見陷阱與對策

陷阱現象對策
忘記 Clear後續正常代碼被誤判為錯誤習慣:If Err Then ... Err.Clear
全域 Resume Next所有錯誤被靜默吞沒,腳本「成功」但結果錯誤嚴禁在腳本頂部直接 On Error Resume Next
COM 物件回傳 HRESULTErr.Number 為負數 (如 -2147217887)用 Hex(Err.Number) 查閱文檔,或 Err.Number And &HFFFF 取低字
語法錯誤無法捕捉On Error 只捕捉**執行時**錯誤,語法錯誤會直接終止編譯開發階段用編輯器語法檢查、測試腳本
Err.Raise 後未清除自訂錯誤殘留影響後續邏輯Raise 後立即 On Error GoTo 0 或由呼叫端 Clear

完整錯誤處理模板


' ===== 模板:安全執行高風險操作 =====
Function SafeExecute(riskyFunc, defaultValue)
    On Error Resume Next
    Dim result
    result = riskyFunc()
    If Err.Number <> 0 Then
        LogError "SafeExecute", Err.Number, Err.Description, Err.Source
        Err.Clear
        result = defaultValue
    End If
    On Error GoTo 0
    SafeExecute = result
End Function

Sub LogError(context, num, desc, src)
    Dim fso, logFile
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set logFile = fso.OpenTextFile("error.log", 8, True) ' 8=ForAppending
    logFile.WriteLine Now & " | " & context & " | " & num & " | " & src & " | " & desc
    logFile.Close
End Sub

' ===== 使用範例 =====
Dim connStr, conn
connStr = "Provider=SQLOLEDB;Data Source=.;Initial Catalog=Test;Integrated Security=SSPI"
Set conn = SafeExecute(Function() 
    Dim c: Set c = CreateObject("ADODB.Connection")
    c.Open connStr
    Set SafeExecute = c
End Function, Nothing)

If conn Is Nothing Then
    WScript.Echo "資料庫連線失敗,請檢查 error.log"
Else
    WScript.Echo "連線成功"
    conn.Close
End If

遷移建議:轉向 PowerShell

新專案建議直接使用 PowerShell,擁有完整 try/catch/finally、throw、$Error 自動變數、結構化例外類型(System.Exception 衍生),除錯與維護效率遠優於 VBScript。

掌握 On Error Resume Next + Err 物件的正確用法,能在必須維護 VBScript 專案時,將錯誤處理從「靜默失敗」提升為「可控、可追蹤、可恢復」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved