【问题标题】:VBScript Newb: Err.Description Returns Empty String, Making Error Log IneffectiveVBScript Newb:Err.Description 返回空字符串,导致错误日志无效
【发布时间】:2021-12-28 17:47:57
【问题描述】:

我想要做什么:

将 VBScript 中的一系列整数变量传递给 SQL Server INSERT INTO 语句。这是由 Windows Scheduler 处理的夜间运行脚本的一部分,用于从基于 Cerner 的系统中获取数据并将其插入到我的 Web 应用程序(我们将其称为“MyApp”)自己的数据库中的表中。我目前正在通过命令提示符以“测试模式”手动运行脚本。

问题:

我在On Error Resume Next 触发错误,并且每次我在日志文件中都有代码WriteLinecstr(now) & " - Error occurred on [insert argument here]: " & Err.Description

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

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

代码sn-p:

    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. 您在此处看到的 sn-p 是我从执行例程的文件中复制过来的代码,并针对我的特定连接进行了修改。
  3. SQL 工作正常,因为我让代码将查询字符串写入脚本的主日志,然后将其粘贴到 Sql Server Management Studio 中,执行它,瞧,新行插入成功。
  4. 与我的 SQL Server 数据库的连接是通过 ODBC 进行的,它在我每次运行时都会通过它的连接测试。
  5. SendErrorNotificationEmail 函数运行正常,因为我确实收到了电子邮件。但是,它也有自己的 On Error Resume Next 实例,它确实会触发,并且它也有相同的命令将 cStr(now()) &amp; " error occurred during email notification of script error: " &amp; Err.Description 写入日志文件(如果是 Err.Number &lt;&gt; 0),错误日志的其余部分如下所示:李>
12/28/2021 12:03:22 PM error occurred during email notification of script error: 

更新 - 12/28,下午 4:00

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

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

修改后的代码:

' (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: 

【问题讨论】:

  • 您的第一条消息Error occurred on connection to MyApp_DB 似乎无论是否发生错误都是写的,所以我希望Err.Description 在“无错误”情况下为空
  • @MartinSmith - 你完全正确。接得好。我将If Err.Number &lt;&gt; 0 条件添加到WriteLine。但我仍然在日志中得到完全相同的错误。
  • 您可以记录显然存在的非零Err.Number 吗?您自己的代码中是否包含任何 Err.Raise 没有您未向我们展示的描述?
  • @MartinSmith - 刚刚将其添加到要写入日志的字符串中。在所有三个错误日志实例中也返回一个空字符串。
  • “我必须使用现有的东西”PowerShell 在每个受支持的 Windows 版本上都有。

标签: sql-server error-handling vbscript odbc


【解决方案1】:

在除最外层脚本之外的所有地方关闭 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

【讨论】:

  • 好消息:根据您建议的调整,我成功执行了 INSERT 语句。坏消息:Err.Number 仍然是 0,Description 在我的日志中仍然是一个空字符串。我将在对 OP 的更新中将修订添加到我的代码中。
  • 虽然重构代码确实有帮助,但这并不是最初的问题。原始的If testmode then 语句如果为真,则尝试写入Err.Description,但此时可能没有错误,因此Err.Description 将为空。如果他们遵循this duplicate question 中的建议,他们一开始就不会遇到这个问题。
【解决方案2】:

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

来一探究竟:根本没有Error。以下是我解决问题的步骤:

  1. 我将错误处理 BACK 移回专用 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

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

【讨论】:

  • VBScript错误处理没有错,只要你懂得如何正确使用。
  • Select 在比较对象实例时不会添加任何内容,因此它永远不会是0,这没有任何意义,无论您是否使用If,您都应该检查Err.NumberSelect 声明。
  • @user692942 - 它不能“永远为 0”,因为它返回 0,Case 处理程序写入日志的行证明了这一点。请停止对我写的所有内容投反对票;不管你坚持什么是“正确的方法”,我的解决方案有效,并且可以帮助其他遇到与Err.Number 相同问题的人。
猜你喜欢
  • 2015-01-13
  • 1970-01-01
  • 2019-05-13
  • 2023-03-16
  • 2020-12-23
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多