Error Handlers

way2bord

Registered User.
Local time
Today, 09:06
Joined
Feb 8, 2013
Messages
177
Is there any reason I shouldn't do the following?
I have the feeling that it's a bad idea, but I can't think why...
(please move if this is better suited for -> VBA?)

ie.

function A (param 1, param 2, param 3...)

errorhandler
if error due to bad param
update param
resume A(param 1, param 2, param 3)

end function
 
I personally wouldn't rely on the error handler. I prefer to code for most foreseeable issues, so I'd be testing the parameters before moving on.
 
>>Is there any reason I shouldn't do the following?<<
Yes, it won’t work.

I know it was meant to be pseudo code but it is too pseudo.
A practical example would be this:-
Code:
Sub TestIT()
    Dim B As String

    A B

End Sub


Sub A(ByVal B As Long)

    MsgBox B
    
End Sub
The above code compiles but the runtime error is raised in TestIt not A.
Therefore, A can not protect itself from the error in TestIt.

Let’s have another look at it:-
Code:
Sub TestIT()
    Dim B As Variant

    B = 1234
    A B         ' << OK

    B = "Fred"
    A B         ' << Fail

End Sub


Sub A(ByVal B As Long)

    MsgBox B
    
End Sub
Here, at runtime, we get away with the first call but not the second.
Again, A can not protect itself from TestIt.

If any rule applies, then the caller must protect the called.
If the called is to protect itself then it must be capable of receiving anything passed from the caller.

Perhaps you could supply a more practical example.

Chris.
 
This example is a bit closer to my thinking.

Instead of dcount, and field switching I'd be testing for connections to a database and database exclusivity; and then performing a number of...error prone operations to manipulate windows files.

It seems much easier - and quicker - to test for fail conditions / errors rather than preemptively identifying and coding in conditional checks. My preference is to do what's easiest -- if I can do so and avoid future bugs.


Code:
Sub CallMyTest()
[INDENT]Dim a As String
a = "myFieldBad"
MsgBox myTest(a)
[/INDENT]End Sub
 
Function myTest(a As String) As Integer
On Error GoTo err_hand
[INDENT]b = DCount(a, "myTbl") ' myTbl exists, myFieldBad Not Exists, myFieldGood exists
myTest = b
[/INDENT]exit_hand:
Exit Function
 
err_hand:
[INDENT]Select Case Err.Number
[INDENT]Case 2471 ' dcount fails on bad parameter
[INDENT]a = "myFieldGood"
myTest = myTest(a)
[/INDENT]Case Else
[INDENT]myTest = 0
MsgBox Err.Number & " " & Err.Description
[/INDENT][/INDENT]End Select
[/INDENT]End Function
 
what Chris has said is correct.

the error is in the calling sub for passing the wrong type of parameter - not in the receiving sub for receiving the wrong parameter

if you must try and do this, then declare the perameter as a variant, and then test it inside the function. that should work.(although you probably will not get a RTE in the same way. )
 
the error is in the calling sub for passing the wrong type of parameter - not in the receiving sub for receiving the wrong parameter

How do you figure that Dave? A valid string value is being passed.
 
@pbaldy - gemma was looking at the ChrisO dummy example and not the more recent clarification.

Addendum / Clarification to OP question:
given the intent:
Instead of dcount, and field switching I'd be testing for connections to a database and database exclusivity; and then performing a number of...error prone operations to manipulate windows files.

It seems much easier - and quicker - to test for fail conditions / errors rather than preemptively identifying and coding in conditional checks. My preference is to do what's easiest -- if I can do so and avoid future bugs.


I'm trying to get a feeling for the dangers of running recursion inside error handlers.


I would appreciate any feedback or thoughts on the following:
- Since the error flag is already active, with no RESUME to reset it, what happens when I run a new function, within the error handler, which contains functional error handlers of its own?


- With an eye towards recursion, How "deep" can error handling go? if I call a function in an error handler, and that function encounters an error and calls another function in its error handler... repeat forever... if each call repairs one of the errors, will the function eventually reach the "top" level without problem?


- Why is coding in the above fashion inappropriate? Again -- I have the gut feeling that this is a very bad idea to abuse error-handlers in this fashion, but at the same time, error-handling specific errors is also a very convenient and quick method for resolving a number of conditional issues.
 
B is not declared, turn on Option Explicit.

On Error GoTo err_hand would reset the error object.

A small change and there is no need for recursion in this case:-

Code:
Option Compare Database
Option Explicit


Sub CallMyTest()
    Dim a As String
    
    a = "myFieldBad"
    MsgBox myTest(a)

End Sub
 
 
Function myTest(a As String) As Integer
    Dim b As Integer
    
Retry:
    On Error GoTo err_hand

    b = DCount(a, "myTbl")

    myTest = b
    
exit_hand:
    Exit Function
 
err_hand:
    Select Case Err.Number

    '    Case 2471 ' dcount fails on bad parameter
        Case 2001 ' dcount fails on bad parameter
            a = "myFieldGood"
            Resume Retry

        Case Else
            myTest = 0
            MsgBox Err.Number & " " & Err.Description
            Resume exit_hand

    End Select

End Function

Resume Retry or GoTo Retry produces the same result.

Produces an infinite loop if "myFieldGood" is also incorrect. Even if there are many names which could be tried, it would require one of the names to be correct in order to get out of the loop. Or a loop counter.

Chris.
 
chris - interesting observation when testing this

your example below fails with a blank string, but not with a numeric string. you do get a difference with byref and byval though. another example of the effect of brackets

Code:
'Chris O's example
Sub TestIT()
Dim B As String
A B
End Sub
 
Sub A(ByVal B As Long)
MsgBox B
End Sub

Code:
'mytests
 
Sub TestIT()
Dim B As String
    B = "4"
    byvalA B 'works
    byvalA (B) 'works
    Call byvalA(B) 'works
 
    byrefA (B) 'works
    'Call byrefA(B) 'type mismatch
    'byrefA B 'type mismatch
End Sub
 
Sub byvalA(ByVal B As Long)
     MsgBox B
End Sub
 
Sub byrefA(ByRef B As Long)
     MsgBox B
End Sub
 

Users who are viewing this thread

Back
Top Bottom