![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | Re: error handling "Wolf Grossi" <wg1@xxxxxx> wrote in message news:f32b8$4a8d277d$55c732a3$10036@xxxxxx Quote: > Hi folks, > > I use a complex vbscript to perform daily tasks; > in this vbscript errrhandling is implemented accordig the below sample: > > > --- > Option Explicit > > main > MsgBox("VBSTest end") > > Sub main() > On Error Resume Next > a = 5 / 0 > checkError Err > end Sub > > Sub checkError(Err) > Dim ErrNum, ErrTxt > ErrNum = Err.Number > ErrTxt = Err.Description > On Error GoTo 0 > if (ErrNum = 0) then > exit Sub > end if > MsgBox(ErrNum & vbTab & ErrTxt) > end Sub > --- > > This works fine, the 'division by zero' message pops up. > > However, if 'checkError' produces another error, e.g, caused by > if (ErrNum == 0) then ... > *after* the statement 'On Error GoTo 0' > the 'Syntaxerror' message does not appear. > > > The statement 'On Error GoTo 0' in a sub apparently does *not* reset the > 'On Error Resume Next' statement. > > > Any pointers on how to implement a robust error handling with vbscript? > > > Thanks for reading and hints > Wolf such as "if ErrNum==0" then wscript.exe terminated the script immediately. On the other hand I feel rather uncomfortable with the structure of your script. There seems little point in calling the error subroutine unless there is an error. I would prefer the simplified script below - it does exactly the same thing as your original script. I would also omit the Main / sub Main() bit. It serves no useful purpose in VB Scripts. On Error Resume Next a = 5 / 0 if err.number <> 0 then checkError Err.number, Err.Description On Error Goto 0 MsgBox("VBSTest end") Sub checkError(ErrNum, ErrTxt) MsgBox(ErrNum & vbTab & ErrTxt) End Sub |
My System Specs![]() |
| | #2 (permalink) |
| | Re: error handling Wolf wrote: Quote: > > I use a complex vbscript to perform daily tasks; > in this vbscript errrhandling is implemented accordig the below sample: > > > --- > Option Explicit > > main > MsgBox("VBSTest end") > > Sub main() > On Error Resume Next > a = 5 / 0 > checkError Err > end Sub > > Sub checkError(Err) > Dim ErrNum, ErrTxt > ErrNum = Err.Number > ErrTxt = Err.Description > On Error GoTo 0 > if (ErrNum = 0) then > exit Sub > end if > MsgBox(ErrNum & vbTab & ErrTxt) > end Sub > --- > > This works fine, the 'division by zero' message pops up. > > However, if 'checkError' produces another error, e.g, caused by > if (ErrNum == 0) then ... > *after* the statement 'On Error GoTo 0' > the 'Syntaxerror' message does not appear. > > > The statement 'On Error GoTo 0' in a sub apparently does *not* reset the > 'On Error Resume Next' statement. > > > Any pointers on how to implement a robust error handling with vbscript? > suspends normal error handling. If an error is raised, execution continues and information is available in the Err object. The statement "On Error GoTo 0" does two things. It clears any error condition and it restores normal error handling. Normal error handling is to halt when there is an error and show an error message. You can use the statement "Err.Clear" to clear any error condition, but not restore normal error handling. The Err object has the properties Number, Description, and Source. You can also raise your own error conditions with "Err.Raise". Maybe you want to use Err.Clear in your Sub. -- Richard Mueller MVP Directory Services Hilltop Lab - http://www.rlmueller.net -- |
My System Specs![]() |
| | #3 (permalink) |
| | Re: error handling Wolf Grossi schrieb: Quote: > Hi folks, > > I use a complex vbscript to perform daily tasks; > in this vbscript errrhandling is implemented accordig the below sample: > > > --- > Option Explicit > > main > MsgBox("VBSTest end") > > Sub main() > On Error Resume Next > a = 5 / 0 > checkError Err > end Sub > > Sub checkError(Err) > Dim ErrNum, ErrTxt > ErrNum = Err.Number > ErrTxt = Err.Description > On Error GoTo 0 > if (ErrNum = 0) then > exit Sub > end if > MsgBox(ErrNum & vbTab & ErrTxt) > end Sub > --- > > This works fine, the 'division by zero' message pops up. > > However, if 'checkError' produces another error, e.g, caused by > if (ErrNum == 0) then ... > *after* the statement 'On Error GoTo 0' > the 'Syntaxerror' message does not appear. > > > The statement 'On Error GoTo 0' in a sub apparently does *not* reset the > 'On Error Resume Next' statement. > > > Any pointers on how to implement a robust error handling with vbscript? As OERN disables error detection/handling for all code upto the OEG0 *in the same scope*, the rule is to allow at most three lines between OERN and OEG0: the statement that may fail and assigning to variable(s) saving the Err object's state: Option Explicit MsgBox "VBSTest begin" 'main main2 MsgBox "VBSTest end" Sub main() On Error Resume Next ' this hides "undefined variable a" a = 5 / 0 checkError Err End Sub Sub main2() Dim a, nErr, sErr On Error Resume Next a = 5 / 0 nErr = Err.Number sErr = Err.Description On Error GoTo 0 checkError2 nErr, sErr end Sub Sub checkError(Err) Dim ErrNum, ErrTxt ErrNum = Err.Number ErrTxt = Err.Description On Error GoTo 0 if (ErrNum = 0) then exit Sub end if ' MsgBox ErrNum & vbTab & ErrTxt MsgBox ErrNum & vbTub & ErrTxt ' no display - "Division by zero" hidden end Sub Sub checkError2( nErr, sErr ) If 0 = nErr Then Exit Sub End If MsgBox nErr & vbTab & sErr ' MsgBox nErr & vbTub & sErr ' "undefined variable vbTub" shown End Sub |
My System Specs![]() |
| | #4 (permalink) |
| | Re: error handling Pegasus [MVP] schrieb: Quote: > "Wolf Grossi" <wg1@xxxxxx> wrote in message > news:f32b8$4a8d277d$55c732a3$10036@xxxxxx Quote: >> Hi folks, >> >> I use a complex vbscript to perform daily tasks; >> in this vbscript errrhandling is implemented accordig the below sample: >> >> >> --- >> Option Explicit >> >> main >> MsgBox("VBSTest end") >> >> Sub main() >> On Error Resume Next >> a = 5 / 0 >> checkError Err >> end Sub >> >> Sub checkError(Err) >> Dim ErrNum, ErrTxt >> ErrNum = Err.Number >> ErrTxt = Err.Description >> On Error GoTo 0 >> if (ErrNum = 0) then >> exit Sub >> end if >> MsgBox(ErrNum & vbTab & ErrTxt) >> end Sub >> --- >> >> This works fine, the 'division by zero' message pops up. >> >> However, if 'checkError' produces another error, e.g, caused by >> if (ErrNum == 0) then ... >> *after* the statement 'On Error GoTo 0' >> the 'Syntaxerror' message does not appear. >> >> >> The statement 'On Error GoTo 0' in a sub apparently does *not* reset the >> 'On Error Resume Next' statement. >> >> >> Any pointers on how to implement a robust error handling with vbscript? >> >> >> Thanks for reading and hints >> Wolf > I was unable to duplicate your observation. When I introduced a syntax error > such as "if ErrNum==0" then wscript.exe terminated the script immediately. > On the other hand I feel rather uncomfortable with the structure of your > script. There seems little point in calling the error subroutine unless > there is an error. I would prefer the simplified script below - it does > exactly the same thing as your original script. I would also omit the Main / > sub Main() bit. It serves no useful purpose in VB Scripts. > > On Error Resume Next > a = 5 / 0 > if err.number <> 0 then checkError Err.number, Err.Description > On Error Goto 0 > MsgBox("VBSTest end") > > Sub checkError(ErrNum, ErrTxt) > MsgBox(ErrNum & vbTab & ErrTxt) > End Sub > > Option Explicit MsgBox "VBSTest begin" On Error Resume Next a = 5 / 0 if err.number <> 0 then checkError Err.number, Err.Description On Error Goto 0 MsgBox "VBSTest end" Sub checkError(ErrNum, ErrTxt) MsgBox ErrNum & vbTub & ErrTxt End Sub the division by zero error will be completely hidden. Removing the "Option Explicit" will cause this error to be shown, but then you get no message concerning the typo vbTub. Whether you prefer to check a failure once in a error handling sub, or often in the calling context is a matter of personal taste/style. The important aspect is that you should have as few/simple/trivial lines as possible between OERN and OEG0. In my opinion, using a main sub or function is a very good practice. It makes it difficult to mess around with global variables, enforces good code structure, and allows to test/work with different ideas/ methods/versions of code in the same script without messy editing. |
My System Specs![]() |
| | #5 (permalink) |
| | Re: error handling "ekkehard.horner" <ekkehard.horner@xxxxxx> wrote in message news:4a8d3838$0$31872$9b4e6d93@xxxxxx-online.net... Quote: > Wolf Grossi schrieb: Quote: >> Hi folks, >> >> I use a complex vbscript to perform daily tasks; >> in this vbscript errrhandling is implemented accordig the below sample: >> >> >> --- >> Option Explicit >> >> main >> MsgBox("VBSTest end") >> >> Sub main() >> On Error Resume Next >> a = 5 / 0 >> checkError Err >> end Sub >> >> Sub checkError(Err) >> Dim ErrNum, ErrTxt >> ErrNum = Err.Number >> ErrTxt = Err.Description >> On Error GoTo 0 >> if (ErrNum = 0) then >> exit Sub >> end if >> MsgBox(ErrNum & vbTab & ErrTxt) >> end Sub >> --- >> >> This works fine, the 'division by zero' message pops up. >> >> However, if 'checkError' produces another error, e.g, caused by >> if (ErrNum == 0) then ... >> *after* the statement 'On Error GoTo 0' >> the 'Syntaxerror' message does not appear. >> >> >> The statement 'On Error GoTo 0' in a sub apparently does *not* reset the >> 'On Error Resume Next' statement. >> >> >> Any pointers on how to implement a robust error handling with vbscript? > > As OERN disables error detection/handling for all code upto the > OEG0 *in the same scope*, the rule is to allow at most three lines > between OERN and OEG0: the statement that may fail and assigning > to variable(s) saving the Err object's state: > > Option Explicit > > MsgBox "VBSTest begin" > 'main > main2 > MsgBox "VBSTest end" > > Sub main() > On Error Resume Next ' this hides "undefined variable a" > a = 5 / 0 > checkError Err > End Sub > > Sub main2() > Dim a, nErr, sErr > On Error Resume Next > a = 5 / 0 > nErr = Err.Number > sErr = Err.Description > On Error GoTo 0 > checkError2 nErr, sErr > end Sub > > Sub checkError(Err) > Dim ErrNum, ErrTxt > ErrNum = Err.Number > ErrTxt = Err.Description > On Error GoTo 0 > if (ErrNum = 0) then > exit Sub > end if > ' MsgBox ErrNum & vbTab & ErrTxt > MsgBox ErrNum & vbTub & ErrTxt ' no display - "Division by zero" hidden > end Sub > > Sub checkError2( nErr, sErr ) > If 0 = nErr Then > Exit Sub > End If > MsgBox nErr & vbTab & sErr > ' MsgBox nErr & vbTub & sErr ' "undefined variable vbTub" shown > End Sub I like your rule: "the rule is to allow at most three lines between OERN and OEG0: the statement that may fail and assigning to variable(s) saving the Err object's state" This reduces the chance that an error will cause program execution to resume at some unexpected place in the program. How do you handle the problem of errors that may occur in If or Case condition statements? -Paul Randall |
My System Specs![]() |
| | #6 (permalink) |
| | Re: error handling Paul Randall schrieb: Quote: > "ekkehard.horner" <ekkehard.horner@xxxxxx> wrote in message > news:4a8d3838$0$31872$9b4e6d93@xxxxxx-online.net... Quote: > I like your rule: "the rule is to allow at most three lines > between OERN and OEG0: the statement that may fail and assigning > to variable(s) saving the Err object's state" > This reduces the chance that an error will cause program execution to resume > at some unexpected place in the program. > > How do you handle the problem of errors that may occur in If or Case > condition statements? Assign the result of the risky expression to a variable in the OERN section and use that in the statements after the OEG0. |
My System Specs![]() |
| | #7 (permalink) |
| | Re: error handling "Richard Mueller [MVP]" <rlmueller-nospam@xxxxxx> wrote in message news:uGc7TwYIKHA.5956@xxxxxx Quote: > Wolf wrote: > Quote: >> >> I use a complex vbscript to perform daily tasks; >> in this vbscript errrhandling is implemented accordig the below sample: >> >> >> --- >> Option Explicit >> >> main >> MsgBox("VBSTest end") >> >> Sub main() >> On Error Resume Next >> a = 5 / 0 >> checkError Err >> end Sub >> >> Sub checkError(Err) >> Dim ErrNum, ErrTxt >> ErrNum = Err.Number >> ErrTxt = Err.Description >> On Error GoTo 0 >> if (ErrNum = 0) then >> exit Sub >> end if >> MsgBox(ErrNum & vbTab & ErrTxt) >> end Sub >> --- >> >> This works fine, the 'division by zero' message pops up. >> >> However, if 'checkError' produces another error, e.g, caused by >> if (ErrNum == 0) then ... >> *after* the statement 'On Error GoTo 0' >> the 'Syntaxerror' message does not appear. >> >> >> The statement 'On Error GoTo 0' in a sub apparently does *not* reset the >> 'On Error Resume Next' statement. >> >> >> Any pointers on how to implement a robust error handling with vbscript? >> > VBScript has limited error handling. The statement "On Error Resume Next" > suspends normal error handling. If an error is raised, execution continues > and information is available in the Err object. The statement "On Error > GoTo 0" does two things. It clears any error condition and it restores > normal error handling. Normal error handling is to halt when there is an > error and show an error message. You can use the statement "Err.Clear" to > clear any error condition, but not restore normal error handling. The Err > object has the properties Number, Description, and Source. You can also > raise your own error conditions with "Err.Raise". Maybe you want to use > Err.Clear in your Sub. could be encountered in a script. Since two of these (syntax and logic) affect the outcome of any piece of script, it becomes difficult for any error handling code to verify its own operation. For this reason, error handling code needs to be simple enough to reduce the chance of a syntax or logic error being included. Further, it is virtually impossible to write code that checks other code for the existence of logic errors. It is generally the job of the scripter to detect and remove these flaws before going into production ;-) /Al |
My System Specs![]() |
| | #8 (permalink) |
| | Re: error handling Al Dunbar schrieb: Quote: > > "Richard Mueller [MVP]" <rlmueller-nospam@xxxxxx> wrote in > message news:uGc7TwYIKHA.5956@xxxxxx Quote: Quote: >> VBScript has limited error handling. The statement "On Error Resume >> Next" suspends normal error handling. If an error is raised, execution >> continues and information is available in the Err object. The >> statement "On Error GoTo 0" does two things. It clears any error >> condition and it restores normal error handling. Normal error handling >> is to halt when there is an error and show an error message. You can >> use the statement "Err.Clear" to clear any error condition, but not >> restore normal error handling. The Err object has the properties >> Number, Description, and Source. You can also raise your own error >> conditions with "Err.Raise". Maybe you want to use Err.Clear in your Sub. OERN desaster a dealing with desaster a with your eyes shut Err.Clear desaster b dealing with desaster b with your eyes shut Err.Clear ... OEG0 I would avoid it. Quote: > To this I would add that there are different types of error conditions > that could be encountered in a script. Since two of these (syntax and > logic) affect the outcome of any piece of script, it becomes difficult > for any error handling code to verify its own operation. For this > reason, error handling code needs to be simple enough to reduce the > chance of a syntax or logic error being included. be handled by OERN. If you can't rule out by design that c is 0 in a = b / c then you guard the computation by If 0 = c Then ... Message, Log, Abort ... Else a = b / c ... End If Such checks needn't/shouldn't be done in OERN sections. OERN is for execptions (and some quirks like registry access). If oFS.FileExists( ... ) Then OERN Open OEG0 If bingo Then "sorry, the cat ate my file" : Exit use the file Else "missing file" End If Quote: > Further, it is virtually impossible to write code that checks other code > for the existence of logic errors. It is generally the job of the > scripter to detect and remove these flaws before going into production ;-) put the EVIL global OERN at the top of each script. |
My System Specs![]() |
| | #9 (permalink) |
| | Re: error handling "Wolf Grossi" <wg1@xxxxxx> wrote in message news:f32b8$4a8d277d$55c732a3$10036@xxxxxx Quote: > Hi folks, > > I use a complex vbscript to perform daily tasks; > in this vbscript errrhandling is implemented accordig the below sample: > > > --- > Option Explicit > > main > MsgBox("VBSTest end") > > Sub main() > On Error Resume Next > a = 5 / 0 > checkError Err > end Sub > > Sub checkError(Err) > Dim ErrNum, ErrTxt > ErrNum = Err.Number > ErrTxt = Err.Description > On Error GoTo 0 > if (ErrNum = 0) then > exit Sub > end if > MsgBox(ErrNum & vbTab & ErrTxt) > end Sub > --- > > This works fine, the 'division by zero' message pops up. > > However, if 'checkError' produces another error, e.g, caused by > if (ErrNum == 0) then ... > *after* the statement 'On Error GoTo 0' > the 'Syntaxerror' message does not appear. > > > The statement 'On Error GoTo 0' in a sub apparently does *not* reset the > 'On Error Resume Next' statement. > > > Any pointers on how to implement a robust error handling with vbscript? > > > Thanks for reading and hints > Wolf Writing a simple script that demonstrates the changes in the order in which statements are executed when errors occur at different locations in the script, is difficult. Your script is an example that demonstrates one aspect in this non-obvious change in order of statement execution. First though, you have to understand that there is a difference between run time errors and syntax errors. Syntax errors typically occur at compile time, before execution begins, so 'On Error Resume Next' is irrelevant at this time. Your script, as posted, generates the proper syntax error. Of course, you can complicate the separation of compile time and run time if you use an execute or eval statement that would require compile time operations to be done during run time. I have not played with the error handling implications of that. It appears that you modified the posted script so that it would be more understandable, and substituted a syntax error statement, > if (ErrNum == 0) then ..., for the actual runtime error-generating statment in your original script. Your sample script further confuses the issues by, in a simple statement, using obvious code that is often intentionally used to generate errors (division by zero) AND subtle code that is almost never used to intentionally generate run time errors (using a non-DIMed variable while within the context of Option Explicit). I have modified your script to make it easier to see what it happening. One change is that msgboxes have been changed to WScript.Echos, so that all the output info can be seen at once, but you will have to run the script under CScript. Open a CMD window and navigate it to the folder containing the test script, then type: cscript filename.vbs and hit enter to run the script. Here is the script: Option Explicit main WScript.Echo "VBSTest end" Sub main() Dim a On Error Resume Next a = 5 / 1 WScript.Echo "Calling checkError when NO error should have occurred" checkError Err WScript.Echo "Returned from checkError when NO error should" & _ " have occurred" & vbcrlf & _ "Error Number = " & Err.Number & vbcrlf & _ "Error Desc = " & err.Description & vbcrlf a = 5 / 0 WScript.Echo "Calling checkError when an error should have occurred" checkError Err WScript.Echo "Returned from checkError when an error should" & _ " have occurred" & vbcrlf & _ "Error Number = " & Err.Number & vbcrlf & _ "Error Desc = " & err.Description & vbcrlf end Sub Sub checkError(Err) WScript.Echo "Entered Sub checkError" Dim ErrNum, ErrTxt ErrNum = Err.Number ErrTxt = Err.Description On Error GoTo 0 if (ErrNum = 0) then WScript.Echo "No error - Exitting Sub checkError" exit Sub end if WScript.Echo "Error occurred: " & ErrNum & vbTab & ErrTxt & _ vbcrlf & "Exitting Sub checkError" end Sub Notice that it "appears" that Sub checkError can return to the main in ONLY two ways: 1) through the end Sub statement, which causes the error number and exitting message to be displayed 2) through the exit Sub statement, which causes the No error exitting message to be displayed. Therefore, it "appears" to be impossible to get a Returned from checkError message unless you get an exitting message. Run the script, and verify that you get something like: Calling checkError when NO error should have occurred Entered Sub checkError No error - Exitting Sub checkError Returned from checkError when NO error should have occurred Error Number = 0 Error Desc = Calling checkError when an error should have occurred Entered Sub checkError Error occurred: 11 Division by zero Exitting Sub checkError Returned from checkError when an error should have occurred Error Number = 0 Error Desc = VBSTest end Now, make one change to the script: Old: if (ErrNum = 0) then New: if (ErrNumX = 0) then This will cause error 500, variable undefined. Now run the new script; you should get something like: Calling checkError when NO error should have occurred Entered Sub checkError Returned from checkError when NO error should have occurred Error Number = 500 Error Desc = Variable is undefined Calling checkError when an error should have occurred Entered Sub checkError Returned from checkError when an error should have occurred Error Number = 500 Error Desc = Variable is undefined VBSTest end Notice that you get Returned from checkError messages, but NO Exitting checkError messages. We have found a magic third way for Sub checkError to return to the calling routine. It is not quite magic, though. The scripting help file says: "On Error Resume Next causes execution to continue with the statement immediately following the statement that caused the run-time error, or with the statement immediately following the most recent call out of the procedure containing the On Error Resume Next statement. This allows execution to continue despite a run-time error. You can then build the error-handling routine inline within the procedure." They should have placed much more emphasis on the second part 'or with the statement immediately following the most recent call out of the procedure containing the On Error Resume Next statement'. I'm pretty sure this statement is mostly true, but not entirely. I'm pretty sure that the important thing is NOT whether the procedure CONTAINS an On Error Resume Next (OERN) statement, but IS whether the call out of that procedure occurs at a location where the OERN is in effect, as in whatever statements are executed between the execution of an OERN and the execution of a subsequent On Error GoTo 0 (OEG0). Since the OERN and OEG0 statements can be executed within IF ... End If and Select Case ... End Select constructs, it may be impossible to tell whether OERN is in effect at any particular line within a routine. (Another reason to use ekkehard.horner's three line rule.) I'm pretty sure the documentation is supposed to mean that even if an error occurs in a statement in a routine ten levels of subroutines/functions deep, and even if perhaps some recursion has occurred, execution will return to the statement following the most recent calling statement that was under the influence of OERN at whatever nesting level that routine was at, at the time of that call. So if you violate ekkehard's rule, you could return from a routine nested ten levels deep directly to a the routine nested three levels deep at the statement following the call to some other routine that started you on the path to the routine ten levels deep. Ask some more questions if this hasn't cleared it up for you. -Paul Randall |
My System Specs![]() |
| | #10 (permalink) |
| | Re: error handling "Wolf Grossi" <wg1@xxxxxx> wrote in message news:cf20b$4a8fc69a$55c732a3$3640@xxxxxx Quote: > Thank you Paul, for elaborating and explaining the error handling issue! > > > Wolf original post: "Any pointers on how to implement a robust error handling with vbscript"? -Paul Randall |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| WMI Error Handling | PowerShell | |||
| Re: Error handling SQl database | VB Script | |||
| error handling | PowerShell | |||
| Crash Course in Error Handling? | PowerShell | |||
| Error Handling | PowerShell | |||