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.Description
和 Err.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:
上下文:
- 我对 VBScript 还很陌生,但已经在 VB.Net 环境中开发了 5 年多,所以它对我来说完全 并不陌生。
- 您在此处看到的代码片段是我从例程运行的文件中复制的代码,并针对我的特定连接进行了修改。
- SQL 工作正常,因为我让代码将查询字符串写入脚本的主日志,然后将其粘贴到 Sql Server Management Studio 中,执行它,瞧,新的已成功插入行。
- 通过 ODBC 连接到我的 SQL 服务器数据库,每次我 运行 它都通过连接测试。
-
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 最糟糕的事情”。它是一个善变、善变的生物。
来一探究竟:完全没有错误下面是我解决问题的步骤:
- 我将错误处理移回了专用的 Sub
ExportDataToMyApp
。
- 我拆分了错误处理并在每次之后添加了
On Error GoTo 0
。它现在分别处理 DataConnExt.Open
和 DataConnExt.Execute
。
- 我没有处理 Err.Number,而是找到了一个使用
Select Case Err
的工作示例,只有两种情况:0 和 Else。
- 我只在错误处理程序中调用了
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 仍在接受新行,所有“成功”行都被写入日志。感谢所有帮助过的人。
我想做什么:
将 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.Description
和 Err.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:
上下文:
- 我对 VBScript 还很陌生,但已经在 VB.Net 环境中开发了 5 年多,所以它对我来说完全 并不陌生。
- 您在此处看到的代码片段是我从例程运行的文件中复制的代码,并针对我的特定连接进行了修改。
- SQL 工作正常,因为我让代码将查询字符串写入脚本的主日志,然后将其粘贴到 Sql Server Management Studio 中,执行它,瞧,新的已成功插入行。
- 通过 ODBC 连接到我的 SQL 服务器数据库,每次我 运行 它都通过连接测试。
-
SendErrorNotificationEmail
运行 功能正确,因为我确实收到了电子邮件。但是,它也有自己的On Error Resume Next
实例,它会触发,并且它也有相同的命令将cStr(now()) & " error occurred during email notification of script error: " & Err.Description
写入日志文件 ifErr.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 最糟糕的事情”。它是一个善变、善变的生物。
来一探究竟:完全没有错误下面是我解决问题的步骤:
- 我将错误处理移回了专用的 Sub
ExportDataToMyApp
。 - 我拆分了错误处理并在每次之后添加了
On Error GoTo 0
。它现在分别处理DataConnExt.Open
和DataConnExt.Execute
。 - 我没有处理 Err.Number,而是找到了一个使用
Select Case Err
的工作示例,只有两种情况:0 和 Else。 - 我只在错误处理程序中调用了
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 仍在接受新行,所有“成功”行都被写入日志。感谢所有帮助过的人。