-1

What I'm trying to do:

Pass a series of integer variables in VBScript to a SQL Server INSERT INTO statement. This is part of a nightly-run script, handled by Windows Scheduler, to grab data from a Cerner-based system and insert it into a table in my web app's (we'll call it "MyApp's") own database. I'm currently running the script in "test mode," manually, through Command Prompt.

The problem:

I get errors firing at On Error Resume Next, and each time, I have the code WriteLine to the log file: cstr(now) & " - Error occurred on [insert argument here]: " & Err.Description.

However, every time, in every instance, Err.Description is just an empty string and doesn't tell me what's going on. On top of that, Err.Number gives me...nothing!

NOTE (12/30/21): It was suggested that my question is similar to this one; however, the accepted answer there is to use Err.Number, which did not work for me, as it kept returning empty/null. My problem was with Err.Description and Err.Number not giving me any information in my log that I can work with.

The code snippet:

    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 

What the error log says:

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: 
   

Context:

  1. I'm fairly new to VBScript, but have been developing in VB.Net environments for over 5 years, so it's not completely foreign to me.
  2. The snippet you see here is code I copied over from a file in which the routine works, modified for my specific connection.
  3. The SQL works correctly, as I had the code write the query string to the script's main log, then pasted it into Sql Server Management Studio, executed it, and voila, the new row was inserted successfully.
  4. The connection to my SQL Server database is through ODBC, which passes its connection test every time I run it.
  5. The function SendErrorNotificationEmail runs correctly, as I do receive the email. However, it also has its own instance of On Error Resume Next that does fire, and it too has the same commands to write cStr(now()) & " error occurred during email notification of script error: " & Err.Description to the log file if Err.Number <> 0, and the rest of the error log reads as follows:
12/28/2021 12:03:22 PM error occurred during email notification of script error: 

Update - 12/28, 4:00pm

Credit to @DavidBrowne-Microsoft for helping me restructure some things and reduce redundant Error handling. Below is a revision of my code. The good news is, the INSERT statement is now successfully being executed when I run the script. The bad news: Err.Number is still <> 0, and still no Description.

One thing I DID learn is that WScript.Quit shouldn't have been there. The whole file is now structured so that my code runs last, and correctly adds its Errors to the error log; upon test-running, the only Errors found were my "phantom Errors."

The revised code:

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

The error log:

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

  • Your first message `Error occurred on connection to MyApp_DB` seems to be written irrespective of whether or not an error occurred so I would expect `Err.Description` to be empty in the "no error" case – Martin Smith Dec 28 '21 at 17:53
  • @MartinSmith - You're absolutely right about that. Good catch. I added the `If Err.Number <> 0` condition to that `WriteLine`. But I'm still getting the same exact errors in the log. – T_O_Massey Dec 28 '21 at 18:04
  • Can you log the non-zero `Err.Number` that apparently exists? Does your own code contain any `Err.Raise` without descriptions that you haven't shown us? – Martin Smith Dec 28 '21 at 18:06
  • @MartinSmith - Just added that to the string to write to log. Also returns an empty string, in all three error log instances. – T_O_Massey Dec 28 '21 at 18:10
  • " I have to work with what is there" PowerShell is there on every supported version of Windows. – David Browne - Microsoft Dec 28 '21 at 18:22
  • Fair enough. I suppose no one uses VBScript by choice. Can you repro the scenario without an Err.Description? What is the Err.Number? What line? I suppose it's possible to that Err.Description is not always set. Error handling is probably the worst thing about VBScript. It's even worse (if you can believe it) than VBA and VB6. – David Browne - Microsoft Dec 28 '21 at 21:12
  • @DavidBrowne-Microsoft - I just tried simply putting `MsgBox " " & Err.Number & " "` inside of the `If Err.Number <> 0` condition. No MsgBox ever appeared. – T_O_Massey Dec 28 '21 at 21:27
  • But what caused the error? Can you add code to reproduce it? – David Browne - Microsoft Dec 28 '21 at 21:27
  • Does this answer your question? [VBScript -- Using error handling](https://stackoverflow.com/questions/157747/vbscript-using-error-handling) – user692942 Dec 29 '21 at 18:57
  • @user692942 - No. The accepted answer there is to use `Err.Number`, which did not work for me, as it kept returning empty/null. My problem was with `Err.Description` and `Err.Number` not giving me any information in my log that I can work with. – T_O_Massey Dec 30 '21 at 18:43
  • @T_O_Massey it did not work for you because you were using it incorrectly. You had the `If testmode then` statement try to write out `Err.Description` but how does it know there is an error without checking `Err.Number` how does it know there is an error? If `Err.Number` equals `0` the `Err.Description` will be blank. Further down writing out the `Err.Number` would be a better approach that way you can determine what exactly is the error that is occuring. The correct approach is to test one statement at a time using `If Err.Number <> 0 Then`, so yes the duplicate is valid. – user692942 Dec 31 '21 at 08:42

2 Answers2

0

Turn off ON ERROR RESUME NEXT everywhere except in your outermost script. So something like:

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 - Microsoft
  • 80,331
  • 6
  • 39
  • 67
  • The good news: working off the adjustments you suggested, I was successful in executing the INSERT statement. The bad news: `Err.Number` is still <> 0, and `Description` is still an empty string in my log. I'll add the revision to my code in an update to the OP. – T_O_Massey Dec 28 '21 at 19:56
  • 1
    While re-structuring the code does help that wasn't the original problem. The original `If testmode then` statement if true tries to write `Err.Description` but at that point it's possible there is no error and so `Err.Description` will be empty. If they followed the advice in [this duplicate question](https://stackoverflow.com/questions/157747/vbscript-using-error-handling) they wouldn't have had this problem in the first place. – user692942 Dec 31 '21 at 08:32
-1

David Browne was not kidding when he says that "Error handling is probably the worst thing about VBScript." It is a fickle, fickle creature.

Come to find out: there was no Error at all. Here are the steps I took to solve the problem:

  1. I moved the Error handling BACK into the dedicated Sub ExportDataToMyApp.
  2. I split up the Error handling and added On Error GoTo 0 after each time. It now handles DataConnExt.Open and DataConnExt.Execute separately.
  3. Instead of dealing with Err.Number, I found a working example of using Select Case Err, with only two cases: 0 and Else.
  4. I only called the CloseObjects Sub within the Error handlers.

Revised and working solution:

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

Lo and behold, the error log file vanished from the folder, the database table was still accepting new rows, and all "success" lines were written to the log. Thank you to all who helped.

  • There is nothing wrong with VBScript error handling as long as you understand how to use it properly. – user692942 Dec 29 '21 at 21:27
  • The `Select` adds nothing as you are comparing an object instance so it will never be `0`, that makes no sense you should be checking `Err.Number` regardless of whether you use an `If` or `Select` statement. – user692942 Dec 31 '21 at 14:17
  • @user692942 - It can't "never be 0," because it *was* returning 0, as evidenced by the line written to the log by the `Case` handler. Please stop downvoting everything I write; regardless of what you insist is "the right way," my solution **works**, and may help others who encounter the same problem with `Err.Number` that I did. – T_O_Massey Jan 03 '22 at 21:55