-
[RESOLVED] Want to make sure i understand error handling
I have routine that emails me error information thru online jMail. It gives the following information:
Date
Computer/name
User/name
App.title
App.minor and major version
App.path
App.exename
Procedure title
Error line number
Error number
Error description
I think i understand the error handling correctly. This is the part i am not sure of:
I know this will produce an error if the file does not exist:
Code:
Sub OpenFile()
On error goto ErrorHandler
On Error Resume Next
Open Myfile For Random As #miFilenumber 'file is created if it does not exist
On error goto ErrorHandler ' reset the error handler
Is this the correct way to write this?
-
Re: Want to make sure i understand error handling
No because you dont have a label for the error handle to go to on error. Plus on error resume next is not that great for error handling.
Code:
Private Sub OpenMyFile()
On Error GoTo MyError
Dim miFilenumber As Integer
miFilenumber = FreeFile
Open Myfile For Random As #miFilenumber
'Do your stuff
Close #miFilenumber
Exit Sub
MyError:
MsgBox Err.Number & " - " & Err.Description, vbOkOnly + vbExclamation, "Error - OpenMyFile"
Close 'Close any file that may be open to prevent error 55
End Sub
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by RobDog888
Plus on error resume next is not that great for error handling.
Why not? Specifically, what exactly can you do with "On Error GoTo <Label>" that you can't do with On Error Resume Next?
-
Re: Want to make sure i understand error handling
Why would you want to supress an error? Its best to handle the error properly rather then "ignoring" it.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by RobDog888
Why would you want to supress an error? Its best to handle the error properly rather then "ignoring" it.
On Error Resume Next doesn't suppress errors any more than On Error GoTo <Label> does, nor does it prevent you from handling them properly.
vb Code:
On Error GoTo SuppressError
Open Myfile For Random As #miFilenumber 'file is created if it does not exist
Exit Sub
SuppressError:
Resume Next
vb Code:
On Error Resume Next
Open Myfile For Random As #miFilenumber 'file is created if it does not exist
Select Case Err.Number
Case ??: MsgBox "File not found"
Case Else
MsgBox "Unexpected Error!"'
Exit Sub
End Select
Exit Sub
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by RobDog888
Why would you want to supress an error? Its best to handle the error properly rather then "ignoring" it.
If you try to open a file that does not exist it produces an error, But it creates the file. I realize i left off the error handling part.
Whta i am trying to do is turn on error handler. The turn it off on the file open
and then turn it back on again
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by isnoend07
If you try to open a file that does not exist it produces an error, But it creates the file. I realize i left off the error handling part.
Whta i am trying to do is turn on error handler. The turn it off on the file open
and then turn it back on again
You did that correctly. Whether you ever should is a debate that approaches religious dogma at times.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by RobDog888
No because you dont have a label for the error handle to go to on error. Plus on error resume next is not that great for error handling.
Code:
Private Sub OpenMyFile()
On Error GoTo MyError
Dim miFilenumber As Integer
miFilenumber = FreeFile
Open Myfile For Random As #miFilenumber
'Do your stuff
Close #miFilenumber
Exit Sub
MyError:
MsgBox Err.Number & " - " & Err.Description, vbOkOnly + vbExclamation, "Error - OpenMyFile"
Close 'Close any file that may be open to prevent error 55
End Sub
I left off the error handling routine in my first post so here it is.
Code:
Sub cmdAdd_Click()
On error goto ErrorHandler
On Error Resume Next
10 Open Myfile For Random As #miFilenumber 'file is created if it does not exist
20 On error goto ErrorHandler ' reset the error handlererrHandler:
ErrorHandler:
SendToSupport "Sum failure", "cmdAdd_Click", Erl, Err.Number, Err.Description
End Sub
-
Re: Want to make sure i understand error handling
Oh where to start lol...
Quote:
On Error Resume Next doesn't suppress errors any more than On Error GoTo <Label> does, nor does it prevent you from handling them properly.
The "Resume" part is actually clearing the error in the Err object and setting it to 0. Thus it gets supressed. An GoTo label will only "handle" the error without resetting the Err object.
In post#5 your second code example will always generate an error message dialog since there is no case or way out for when there is no error.
@isnoend07, you dont have an Exit Sub or such to bypass your "ErrorHandler:" routine. It will always appear as there is an error.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by RobDog888
Oh where to start lol...
The "Resume" part is actually clearing the error in the Err object and setting it to 0. Thus it gets supressed. An GoTo label will only "handle" the error without resetting the Err object.
In post#5 your second code example will always generate an error message dialog since there is no case or way out for when there is no error.
@isnoend07, you dont have an Exit Sub or such to bypass your "ErrorHandler:" routine. It will always appear as there is an error.
Had that happen before Left of the Exit Sub
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by RobDog888
Oh where to start lol...
The "Resume" part is actually clearing the error in the Err object and setting it to 0. Thus it gets supressed....
That's not true Rob. Try this
Code:
On Error GoTo ErrorRoutine
On Error Resume Next
Err.Raise 6
MsgBox Err.Number
On Error GoTo ErrorRoutine
Exit Sub
ErrorRoutine:
End Sub
-
Re: Want to make sure i understand error handling
Sure its true. The line in your example is resetting the error with a new "On Error GoTo".
-
Re: Want to make sure i understand error handling
See with this example the second msgbox will show a 0 error because of the Resume in the error handling routine.
Code:
Option Explicit
Private Sub Form_Load()
On Error GoTo ErrorRoutine
MsgBox 1 / 0
MsgBox Err.Number
Exit Sub
ErrorRoutine:
MsgBox Err.Number
Resume Next
End Sub
Now see if we throw in a "On Error "GoTo" it will again be 0 because the err object gets reset with each new "on error" assignment.
Code:
Option Explicit
Private Sub Form_Load()
On Error GoTo ErrorRoutine
MsgBox 1 / 0
On Error GoTo ErrorRoutine
MsgBox Err.Number
Exit Sub
ErrorRoutine:
MsgBox Err.Number
Resume Next
End Sub
-
Re: Want to make sure i understand error handling
Rob I don't want to get into a semantic argument with you but I use code like Ellis' second example and it works just fine and that's all I'm saying.
-
Re: Want to make sure i understand error handling
Me too but the procedure you mention will always generate a error message box since if there is no error it will go to the Case Else part is what I was saying. Also the "??" part needs a number or value as its not correct. Try this
Code:
Option Explicit
Private Sub Form_Load()
On Error Resume Next
' Open "" For Random As #1 'file is created if it does not exist
Select Case Err.Number
Case 11: MsgBox "File not found"
Case Else
MsgBox "Unexpected Error!" 'THIS WILL ALWAYS FIRE WHEN NO ERROR
Exit Sub
End Select
Exit Sub
End Sub
-
Re: Want to make sure i understand error handling
Basically, if you want only to have On Error Resume Next for one thing that may raise an error, but don't want it for other processing as that can't cause errors. The coding must be careful for this to be true, numeric variables should not overlap etc. - file handling though has things that you can't control, but anyway:
Code:
On Error Resume Next
Open Filename For Random As #FF
If Err.Number = 0 Then
On Error Goto 0
' do other processing
Close #FF
Else
MsgBox "Error #" & Err.Number & ": " & Err.Description, vbExclamation, "Could not open file"
End If
However I tend to favor API functions simply because you can often either get the error number as a return value or via GetLastError. Of course that means a bit more coding to get the textual error messages, but I find it less messy anyway. Also, not all errors that are raised are execution ending critical, some ones you can just ignore, as long as you don't continue processing assuming there was no error.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by RobDog888
Me too but the procedure you mention will always generate a error message box since if there is no error it will go to the Case Else part is what I was saying. Also the "??" part needs a number or value as its not correct. Try this
Code:
Option Explicit
Private Sub Form_Load()
On Error Resume Next
' Open "" For Random As #1 'file is created if it does not exist
Select Case Err.Number
Case 11: MsgBox "File not found"
Case Else
MsgBox "Unexpected Error!" 'THIS WILL ALWAYS FIRE WHEN NO ERROR
Exit Sub
End Select
Exit Sub
End Sub
Well yes, his example is flawed in that respect but I was responding to your "The "Resume" part is actually clearing the error in the Err object and setting it to 0" assertion which obviously isn't true or else code like Ellis' would never work properly.
-
Re: Want to make sure i understand error handling
No, it is true. Run this and you will see that error 11 will be reset to 0 because of the Resume Next. If it didnt reset the err object then it would msgbox 11 in both msgbox calls.
Code:
Option Explicit
Private Sub Form_Load()
On Error GoTo MyError
MsgBox 1 / 0
MsgBox Err.Number
Exit Sub
MyError:
MsgBox Err.Number
Resume Next
End Sub
-
Re: Want to make sure i understand error handling
RobDog, you're talking about an entirely different thing there. Basically, you're correct in what you're saying, but the line On Error Resume Next does not cause the Err object to be reseted:
Code:
Option Explicit
Private Sub Form_Load()
On Error Resume Next
MsgBox 1 / 0
MsgBox Err.Number
MsgBox Err.Number
End Sub
You get two message boxes with "11". Ellis Dee and MartinLiss are not talking about Resume Next of On Error Goto system, they're talking about not using Goto at all.
-
Re: Want to make sure i understand error handling
Yes, finally someone sees what I am trying to say lol. But your example only has one "On Error" statement so of course it wont "reset" the err object
This will show the reset
Code:
Option Explicit
Private Sub Form_Load()
On Error Resume Next
MsgBox 1 / 0
MsgBox Err.Number ' 11
On Error Resume Next
MsgBox Err.Number ' 0
End Sub
-
Re: Want to make sure i understand error handling
This backs up my claim in addition to the code example
http://msdn.microsoft.com/en-us/libr...92(VS.60).aspx
Quote:
The Err object's properties are reset to zero or zero-length strings ("") after an Exit Sub, Exit Function, Exit Property or Resume Next statement within an error-handling routine.
-
Re: Want to make sure i understand error handling
Apologies for the sloppy example. I was just posting pseudocode, which I would have thought was obvious by the "Case ??" statement.
Rob, we all get what you're saying. It is trivially easy to show that a stand-alone "Resume Next" statement does indeed reset the error object. Nobody has disputed that at any point in this thread.
What you're missing is that you claimed that using "On Error Resume Next" suppresses errors, meaning you would then be unable to handle them in code. It is also trivially easy to demonstrate that this is untrue; you can fairly easily set up robust error handling only using On Error Resume Next. As an added bonus, handling errors with On Error Resume Next doesn't introduce any of those dirty GoTo statements into the code.
My original point was that On Error Resume Next has gotten a bad rap much like GoTo has. There is nothing bad or wrong about using On Error Resume Next to handle errors; it doesn't suppress them any more than On Error GoTo <Label> does.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by RobDog888
Yes, finally someone sees what I am trying to say lol. But your example only has one "On Error" statement so of course it wont "reset" the err object
This will show the reset
Code:
Option Explicit
Private Sub Form_Load()
On Error Resume Next
MsgBox 1 / 0
MsgBox Err.Number ' 11
On Error Resume Next
MsgBox Err.Number ' 0
End Sub
For the above its because only one error handler can be active per procedure... above is not erroneous, its just being interpreted incorrectly... you have two error handling blocks, and the error is not thrown in second block (already handled is implied and that intention will have to be coded accordingly by programmer). It is similar to having two try {} catch {} constructs in Java/C++ one after the other (note not nested)... so the second block really should not care about the exception handling (catch {} section) of preceeding block (again not a parent block).
Same with Resume Next in label... it is implied that you are leaving catch section, or error has been handled, or algorithm goes through several try.. catch sections with only one of them active at any given time... hence resetting of err object due to scope of error that is not cascaded (should have been raised/thrown if it will not be handled by exception code) to calling procedure.
I believe RobDog888 was simply trying to point out that resume next is more vulnerable to misuse especially for those coding exception handling for the first time or those who are unaware of the intricacies of throwing/cascading errors and block scope of errors...
-
Re: Want to make sure i understand error handling
I guess one of the biggest things I don't like with On Error statements is that if you have an If statement and an error happens on that line, the code just keeps on executing as if condition was True.
Example of both On Error Goto and On Error Resume Next:
Code:
Option Explicit
Private Sub Form_Load()
On Error Resume Next
If 1 / 0 Then
MsgBox "What the..."
Else
MsgBox "I'd rather expect this"
End If
On Error GoTo ErrorHandler
If 1 / 0 Then
MsgBox "What the..."
Else
MsgBox "I'd rather expect this"
End If
Exit Sub
ErrorHandler:
' uh, how I could do anything here to prevent getting a True condition in the If statement?
Resume Next
End Sub
I just don't see a way around this, it can be kind of skipped by using a Boolean variable to hold the If result, but sometimes this may not be possible (multiple Elses where it may be wanted that they only occur if the previous one was not true).
-
Re: Want to make sure i understand error handling
Code like Ellis' (once corrected) would handle it just fine.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by Merri
I just don't see a way around this, it can be kind of skipped by using a Boolean variable to hold the If result, but sometimes this may not be possible (multiple Elses where it may be wanted that they only occur if the previous one was not true).
But that's how it goes with API, yes?
Note sure what you mean by not being able to do the boolean method for multiple elses. Could you throw together some pseduocode? Don't bother if it's a PITA.
leinad, kudos for the great explanation. I never really put it together that you can only have one error trap active at a time. I mean, I would never have thought you could have multiple ones going, but I just never internalized the idea.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by Merri
I guess one of the biggest things I don't like with On Error statements is that if you have an If statement and an error happens on that line, the code just keeps on executing as if condition was True.
Example of both
On Error Goto and
On Error Resume Next:
Code:
Option Explicit
Private Sub Form_Load()
On Error Resume Next
If 1 / 0 Then
MsgBox "What the..."
Else
MsgBox "I'd rather expect this"
End If
On Error GoTo ErrorHandler
If 1 / 0 Then
MsgBox "What the..."
Else
MsgBox "I'd rather expect this"
End If
Exit Sub
ErrorHandler:
' uh, how I could do anything here to prevent getting a True condition in the If statement?
Resume Next
End Sub
I just don't see a way around this, it can be kind of skipped by using a Boolean variable to hold the If result, but sometimes this may not be possible (multiple Elses where it may be wanted that they only occur if the previous one was not true).
That's good to know. Thanks for the advice.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by Ellis Dee
But that's how it goes with API, yes?
Note sure what you mean by not being able to do the boolean method for multiple elses. Could you throw together some pseduocode? Don't bother if it's a PITA.
leinad, kudos for the great explanation. I never really put it together that you can only have one error trap active at a time. I mean, I would never have thought you could have multiple ones going, but I just never internalized the idea.
Even with other languages you can only have one active try catch block... another POV on the reset feature of Resume Next is if it weren't so then you would be bouncing back and forth indefinitely between code and exception handling section (same error re-raised so you end up back in label).
In lieu of formal try catch block in VB, resume next transfer the burden of implementing catch construct on the programmer... it could be the next line or several lines after but it is expected that programmer will have to implement the check for existence of error and its handling, compiler doesn't check this as there is no formalized counterpart/pair for the resume next line (in other languages a try must have a corresponding catch or it won't compile) and due to spaghetti code nature of exception handling, hence vulnerable to misuse.
-
Re: Want to make sure i understand error handling
Didn't realize i was opening up such a large debate. I have put a lot of effort for error handling into my my project lately. eg:
Errors are reported to me by email thru a ocx and an online Jmail asp page. This email gives the following information:
Windows version, Processor Info, program name, exe-name, exe version-major and minor, app.path, form or bas name, function name, error number, error description and line number. This info is also posted to a users log file in case of no internet connection.
After all these postings I am not sure if I have got a answer:
My project has grown to 43 forms, 45 modules and 21 classes with thousands of line of code. I can only think of 2 places i have used On Error Resume Next.
1. A setfoucus on a textbox when the form may not be visible
2. Open a file that does not exist.
So just to be clear I am handling this right, is this the correct way ?
Code:
Sub Comman1_Click()
On Error Goto E
some code
more code
On Error Resume Next 'in case form is not visible
Text1.setfocus
On Error Goto E
more code
more code
Exit Sub
E:
Msgbox "Error"
End Sub
-
Re: Want to make sure i understand error handling
isnoend: there is nothing wrong with that, all errors get handled, and the error raised by SetFocus is omitted.
Personally though I'd simply make things so that the SetFocus line would never even get executed unless it can be.
Quote:
Originally Posted by MartinLiss
Code like Ellis' (once corrected) would handle it just fine.
Would it? There is a case of a problem:
Code:
On Error Resume Next
' just imagine any error happening on the If statement...
' an error that you have no control over (external library or a VB method)
If 1 / 0 Then
If Err.Number = 0 Then
' ...
Else
' problem: I would like to continue with the next ElseIf statement
' and I don't want to unnecessarily duplicate code
End If
ElseIf BlahBlah Then
' ...
Else
' ...
End If
Another problem is that any error on the line will omit all the rest of the line, so you can't do something like this:
Code:
If 1 / 0 And Err.Number = 0 Then
In comparison, with many API functions I could do this:
Code:
If CallToAPI(Something) = 0 Then
' everything is fine, continue
Else
' error occurred, do something else or just fail
' (of course, some API don't allow to use GetLastError but return the error value instead)
End If
This is also why I prefer making functions that return a Boolean instead of using Err.Raise and try to figure out which error number I should use. Most often it is not important to know which error occurred, just that you failed to get the result you wanted.
Anyway, my head is a bit fuzzy now and I can't bring out the exact thing that I'm really thinking about... going to be sick or something.
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by isnoend07
Didn't realize i was opening up such a large debate. I have put a lot of effort for error handling into my my project lately. eg:
Errors are reported to me by email thru a ocx and an online Jmail asp page. This email gives the following information:
Windows version, Processor Info, program name, exe-name, exe version-major and minor, app.path, form or bas name, function name, error number, error description and line number. This info is also posted to a users log file in case of no internet connection.
After all these postings I am not sure if I have got a answer:
My project has grown to 43 forms, 45 modules and 21 classes with thousands of line of code. I can only think of 2 places i have used On Error Resume Next.
1. A setfoucus on a textbox when the form may not be visible
2. Open a file that does not exist.
So just to be clear I am handling this right, is this the correct way ?
Code:
Sub Comman1_Click()
On Error Goto E
some code
more code
On Error Resume Next 'in case form is not visible
Text1.setfocus
On Error Goto E
more code
more code
Exit Sub
E:
Msgbox "Error"
End Sub
Normally you would need to Err.Clear within a Resume Next block but error will go out of scope anyway (reset) since you are starting up another block with succeeding On error Goto E. That code will work, but IMO it would be better practice to set aside separate exception handling blocks (consider possible future enhancements/updates) rather than reusing same one even if code is the same... this is in line with try..catch pairing concept or design would be more similar to the block exception model and less spaghetti like code.
Please bear in mind that VB does not directly support nesting of error handling, it has no direct counterpart for following:
Code:
try
{ try
{
}
catch (Exception ex)
{
}
}
catch (Exception ex)
{ try
{
}
catch (Exception ex)
{
}
}
Above will have to be implemented as function calls (nested exception handling in the functions instead) with you checking the return values. Again, in consideration of language shortcoming, it is left to the programmer to implement counterpart for following:
Code:
try 'this is the first On Error block
{
}
catch (Exception exA)
{
}
try 'this is the next On Error block, please note that this isn't obvious in VB syntax
{
}
catch (Exception exB)
{ 'this section should not concern itself with exA
'which should already have been handled in preceding block or raised to calling proc
}
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by isnoend07
So just to be clear I am handling this right, is this the correct way ?
Looks pretty standard to me, but I would second Merri's advice. I try to never intentionally raise errors, which is what your code is doing. (Trying to SetFocus without first checking if you can.) I'd try something like this:
Code:
Sub Comman1_Click()
On Error Goto E
some code
more code
If Not (Screen.ActiveForm Is Nothing) Then
If Screen.ActiveForm.Name = "<Whatever the form name is>" Then
Text1.setfocus
End If
End If
more code
more code
Exit Sub
E:
Msgbox "Error"
End Sub
-
Re: Want to make sure i understand error handling
Quote:
Originally Posted by Merri
Would it? There is a case of a problem:
How is this example a problem with On Error Resume Next but not with On Error GoTo <Label>?
-
Re: [RESOLVED] Want to make sure i understand error handling
I meant it is a problem with On Error in general (as I pretty much continued with the theme of my earlier post, not with the RobDog theme [hey, from now on, On Error Goto ... Resume Next is a RobDog theme!]).
-
Re: [RESOLVED] Want to make sure i understand error handling
Quote:
Originally Posted by Merri
I meant it is a problem with On Error in general
Ah, sorry. Looking back, I see you even clearly stated as such. My bad for not reading for comprehension.
-
Re: [RESOLVED] Want to make sure i understand error handling
I also use this one on all of my handlers, modules and Forms. It goes like this:
OnError:
On Error GoTo 0
0 Exit Sub
Exit Sub
If there is an error in the code or something happens to the computer, it will automatically remove the program from memory, execution and then end the program very quickly. Also there isn't any error checking in this sub routine. But that can be used on the Error Handler sub routine. Which was stated in the posts above in this very thread.
-
Re: [RESOLVED] Want to make sure i understand error handling
Quote:
Originally Posted by ThEiMp
I also use this one on all of my handlers, modules and Forms. It goes like this:
OnError:
On Error GoTo 0
0 Exit Sub
Exit Sub
If there is an error in the code or something happens to the computer, it will automatically remove the program from memory, execution and then end the program very quickly. Also there isn't any error checking in this sub routine. But that can be used on the Error Handler sub routine. Which was stated in the posts above in this very thread.
Why are you ending the exception handling block in the error handler? You are misusing On Error Goto 0, it is supposed to end an error handling block and should not be used to "sweep an error under the rug". Proper usage is the following
Code:
On Error Goto SampleErr 'start of error handling block
'errors in this block's code handled by SampleErr
On Error Goto 0 'end of error handling block. Relate to End If which ends an If..Else block.
'code after block are unhandled
Exit Sub
SampleErr:
'handle the error
Err.Clear 'or resume next
End Sub