VBScript Newb:Err.Description Returns 空字符串,使错误日志无效

VBScript Newb: Err.Description Returns Empty String, Making Error Log Ineffective

我想做什么:

将 VBScript 中的一系列整数变量传递给 SQL 服务器 INSERT INTO 语句。这是 nightly-运行 脚本的一部分,由 Windows 调度程序处理,用于从基于 Cerner 的系统中获取数据并将其插入到我的网络应用程序的 table 中(我们将称它为“MyApp's”)自己的数据库。我目前 运行 通过命令提示符手动将脚本设置为“测试模式”。

问题:

我在 On Error Resume Next 时遇到错误,每次,我都会将代码 WriteLine 写入日志文件:cstr(now) & " - Error occurred on [insert argument here]: " & Err.Description.

但是,每次,在每个实例中,Err.Description 只是一个空字符串,并没有告诉我发生了什么。最重要的是,Err.Number 给我...什么都没有!

注意 (12/30/21):有人建议我的问题类似于 this one;但是,那里接受的答案是使用 Err.Number 对我没有用 ,因为它一直返回 empty/null。我的问题是 Err.DescriptionErr.Number 没有在我的日志中提供任何我可以使用的信息。

代码片段:

    Set DataConnExt = CreateObject("ADODB.Connection")
    DataConnExt.CommandTimeout = 90
    DataConnExt.ConnectionTimeout = 90
    If testmode then                                        'tesmode = True, in this case
        sDsn = "MyAppTST"
    else
        sDsn = "MyApp"
    End If
    sUser = "pseudonym"
    sPWD = "***********"
    On Error Resume Next

    If testmode then
        objErrLogFile.WriteLine "   "
        objErrLogFile.WriteLine cStr(now()) & " Error occurred on connection to MyApp_DB: "
        objErrLogFile.WriteLine "   " & Err.Description
    End If

    DataConnExt.Open "DSN=" & sDSN , sUser, sPWD

    If testmode then
        MidnightMailingLog.WriteLine cstr(now) & " - MyApp Export Query: " & sql
    End If

    errMessage = ""

    If Err.Number <> 0 then
        errMessage = Err.Description
        errDesc = "ERROR occurred while executing export to MyApp DB: " & errMessage
        LogError(errDesc)
        SendErrorNotificationEmail              
        WScript.Quit 99
    End If

    DataConnExt.Close
    Set DataConnExt = Nothing
    rsExport.Close
    Set rsExport = Nothing
    
    On Error GoTo 0 

错误日志的内容:

12/28/2021 12:03:22 PM Error occurred on connection to MyApp_DB: 
   
12/28/2021 12:03:22 PM - ERROR occurred while executing export to MyApp DB: 
   

上下文:

  1. 我对 VBScript 还很陌生,但已经在 VB.Net 环境中开发了 5 年多,所以它对我来说完全 并不陌生。
  2. 您在此处看到的代码片段是我从例程运行的文件中复制的代码,并针对我的特定连接进行了修改。
  3. SQL 工作正常,因为我让代码将查询字符串写入脚本的主日志,然后将其粘贴到 Sql Server Management Studio 中,执行它,瞧,新的已成功插入行。
  4. 通过 ODBC 连接到我的 SQL 服务器数据库,每次我 运行 它都通过连接测试。
  5. SendErrorNotificationEmail 运行 功能正确,因为我确实收到了电子邮件。但是,它也有自己的 On Error Resume Next 实例,它会触发,并且它也有相同的命令将 cStr(now()) & " error occurred during email notification of script error: " & Err.Description 写入日志文件 if Err.Number <> 0,以及错误日志的其余部分全文如下:
12/28/2021 12:03:22 PM error occurred during email notification of script error: 

更新 - 12/28,4:00pm

感谢@DavidBrowne-Microsoft 帮助我重组了一些东西并减少了冗余的错误处理。以下是我的代码的修订版。好消息是,当我 运行 脚本时,现在可以成功执行 INSERT 语句。坏消息:Err.Number 仍然 <> 0,仍然没有 Description

我学到的一件事是 WScript.Quit 不应该在那里。整个文件现在的结构使得我的代码 运行 在最后,并正确地将其错误添加到错误日志中;在测试-运行ning 时,发现的唯一错误是我的“幻象错误”。

修改后的代码:

' (Beginning of Sub -- Everything you see here is within an "If testmode" condition)
' ...

    On Error Resume Next

    ExportDataToMyApp(sqlA)

    If Err.Number <> 0 then
        errMessage = Err.Description & "; Err.Number: " & Err.Number
        errDesc = "ERROR occurred while executing export to MyApp DB: " & errMessage 
        LogError(errDesc)
        ErrCnt = ErrCnt + 1             'necessary for error logging
        'SendErrorNotificationEmail     'don't worry about this one     
    Else
        MidnightMailingLog.WriteLine cstr(now) & " - SQL Server INSERT to MyApp executed successfully."
    End If

    CloseObjects()

End Sub

' *********************************

Sub ExportDataToMyApp(ByRef sql)
    Set DataConnExt = CreateObject("ADODB.Connection")
    DataConnExt.CommandTimeout = 90
    DataConnExt.ConnectionTimeout = 90
    If testmode then
        sDsn = "MyAppTST"
    else
        sDsn = "MyApp"
    End If
    sUser = "pseudonym"
    sPWD = "***********"

    DataConnExt.Open "DSN=" & sDSN , sUser, sPWD

    ' ACTUALLY, I THINK THE FIX FOR THE INSERT STATEMENT WAS HERE, BECAUSE I WAS REFERENCING THE WRONG sql VARIABLE (there are several in this vbs file).
    Set rsExport = DataConnExt.Execute(sql,Recs,1)  

End Sub

' **************************

Sub LogError(eDesc)
    objErrLogFile.WriteLine "   "
    objErrLogFile.WriteLine(cstr(now()) & " - " & eDesc)
End Sub

' ***************************************

Sub CloseObjects()
    rsExport.Close
    Set rsExport = Nothing

    DataConnExt.Close
    Set DataConnExt = Nothing
End Sub

错误日志:

   
12/28/2021 2:52:59 PM - ERROR occurred while executing export to MyApp DB: 

除了最外层的脚本之外,在所有地方都关闭 ON ERROR RESUME NEXT。所以像:

sub LogError(error)
  WScript.Echo error
end sub

    
sub Run(testmode)

    Set DataConnExt = CreateObject("ADODB.Connection")
    DataConnExt.CommandTimeout = 90
    DataConnExt.ConnectionTimeout = 90
    If testmode then                                        'tesmode = True, in this case
        sDsn = "MyAppTST"
    else
        sDsn = "MyApp"
    End If
    sUser = "pseudonym"
    sPWD = "***********"

    DataConnExt.Open "DSN=" & sDSN , sUser, sPWD

    If testmode then
        MidnightMailingLog.WriteLine cstr(now) & " - MyApp Export Query: " & sql
    End If


    DataConnExt.Close
    Set DataConnExt = Nothing
    rsExport.Close
    Set rsExport = Nothing
    
end sub

on error resume next
Run(True)
If Err.Number <> 0 then
    errMessage = Err.Description
     errDesc = "ERROR occurred while executing export to MyApp DB: " & errMessage 
     LogError(errDesc)
     'SendErrorNotificationEmail              
     WScript.Quit 99
End If

David Browne 不是在开玩笑,他说“错误处理可能是 VBScript 最糟糕的事情”。它是一个善变、善变的生物。

来一探究竟:完全没有错误下面是我解决问题的步骤:

  1. 我将错误处理移回了专用的 Sub ExportDataToMyApp
  2. 我拆分了错误处理并在每次之后添加了 On Error GoTo 0。它现在分别处理 DataConnExt.OpenDataConnExt.Execute
  3. 我没有处理 Err.Number,而是找到了一个使用 Select Case Err 的工作示例,只有两种情况:0 和 Else。
  4. 我只在错误处理程序中调用了 CloseObjects Sub。

修改后的有效解决方案:

' (Beginning of Sub -- Everything you see here is within an "If testmode" condition)
' ...

    ExportDataToMyApp(sqlA)

End Sub

' *********************************

Sub ExportDataToMyApp(ByRef sql)
    Set DataConnExt = CreateObject("ADODB.Connection")
    DataConnExt.CommandTimeout = 90
    DataConnExt.ConnectionTimeout = 90
    If testmode then 
        sDsn = "MyAppTST"
    else
        sDsn = "MyApp"
    End If
    sUser = "pseudonym"
    sPWD = "***********"

    On Error Resume Next
    DataConnExt.Open "DSN=" & sDSN , sUser, sPWD
    Select Case Err
        Case 0
            MidnightMailingLog.WriteLine cstr(now) & " - Open Connection to MyApp_DB executed successfully."
        Case Else
            LogError(Err.Description)
            ErrCnt = ErrCnt + 1
            SendErrorNotificationEmail
            On Error Goto 0
            CloseObjects
    End Select
    On Error GoTo 0

    On Error Resume Next
    Set rsExport = DataConnExt.Execute(sql,Recs,1)
    Select Case Err
        Case 0
            MidnightMailingLog.WriteLine cstr(now) & " - SQL Server INSERT to MyApp executed successfully."
        Case Else
            LogError(Err.Description)
            ErrCnt = ErrCnt + 1
            SendErrorNotificationEmail
            On Error Goto 0
            CloseObjects
    End Select
    On Error Goto 0

End Sub

你看,错误日志文件从文件夹中消失了,数据库 table 仍在接受新行,所有“成功”行都被写入日志。感谢所有帮助过的人。