Right way to handle error?

Discussion in 'AutoCAD' started by MP, Jul 27, 2004.

  1. MP

    MP Guest

    Is this right?

    Sub SomeSub()
    Dim oDim As AcadEntity
    Dim vpt As Variant

    'line label
    Choice:

    'here's where I want to handle a certain error possibility
    On Error GoTo errhand

    '--------------question ------------------------------------------
    'or does On Error go before line label?
    '--------------question ------------------------------------------

    ThisDrawing.Utility.GetEntity oDim, vpt, "Select dimension to OK"
    While Not TypeOf oDim Is AcadDimension
    ThisDrawing.Utility.GetEntity oDim, vpt, "Not a dimension, Select
    dimension to OK"
    Wend

    '--------------question ------------------------------------------
    'does this go here to clear out the error handling???
    '(so that if other errors are encountered they just bomb the routine)
    On Error GoTo 0
    '--------------question ------------------------------------------


    '''---------rest of routine-----------

    '''and at end of sub there's the error handler
    '------------------------------
    errhand:
    If UserEscaped Then 'UserEscaped is function that returns t or f (esc key)
    Exit Sub
    Else Go To Choice
    End If
    '------------------------------
    If Not oDim is Nothing then Set oDim = Nothing
    End Sub

    I've never been clear on how to use "on Error goto 0" or where to put it in
    the program flow
    I'm also not clear on whether OnError statements are 'localized' to the sub
    in which they occur or if they can 'spill over' into following subs or
    routines that may follow in a larger program
    ie
    I've seen posts (mostly TT) that said On Error Resume Next is the wrong way
    to go about it because it can mask other errors.
    So I'm trying to figure out how to handle a specific error condition, then
    reset so as to let errors be "seen" if they occur after the special section
    where I "expect" an error.

    tia
    Mark
     
    MP, Jul 27, 2004
    #1
  2. You have the framework pretty close. I would put the statement

    On Error GoTo errhand

    before the looping construct's label.


    On Error GoTo 0 does clear the error handler. An error handler defined in an
    upper level procedure will still be active in a subr if the subr does not
    redefine the error handler. See below code as a sample. Step thru Test and
    notice the results in the Immediate window. Then run just the RunSubTest
    procedure by itself and notice what happens. Also experiment with placing On
    Error GoTo 0 before the call to the subr, and also create a error handler
    for the subr.

    Sub Test()
    On Error GoTo oops

    Debug.Print "ok code"
    Err.Raise 1

    RunSubTest
    Exit Sub

    oops:
    Debug.Print "I ran!"
    Err.Clear
    Resume Next
    End Sub

    Private Sub RunSubTest()
    Debug.Print "sub ok code"
    Err.Raise 1
    End Sub



    --
    R. Robert Bell


    Is this right?

    Sub SomeSub()
    Dim oDim As AcadEntity
    Dim vpt As Variant

    'line label
    Choice:

    'here's where I want to handle a certain error possibility
    On Error GoTo errhand

    '--------------question ------------------------------------------
    'or does On Error go before line label?
    '--------------question ------------------------------------------

    ThisDrawing.Utility.GetEntity oDim, vpt, "Select dimension to OK"
    While Not TypeOf oDim Is AcadDimension
    ThisDrawing.Utility.GetEntity oDim, vpt, "Not a dimension, Select
    dimension to OK"
    Wend

    '--------------question ------------------------------------------
    'does this go here to clear out the error handling???
    '(so that if other errors are encountered they just bomb the routine)
    On Error GoTo 0
    '--------------question ------------------------------------------


    '''---------rest of routine-----------

    '''and at end of sub there's the error handler
    '------------------------------
    errhand:
    If UserEscaped Then 'UserEscaped is function that returns t or f (esc key)
    Exit Sub
    Else Go To Choice
    End If
    '------------------------------
    If Not oDim is Nothing then Set oDim = Nothing
    End Sub

    I've never been clear on how to use "on Error goto 0" or where to put it in
    the program flow
    I'm also not clear on whether OnError statements are 'localized' to the sub
    in which they occur or if they can 'spill over' into following subs or
    routines that may follow in a larger program
    ie
    I've seen posts (mostly TT) that said On Error Resume Next is the wrong way
    to go about it because it can mask other errors.
    So I'm trying to figure out how to handle a specific error condition, then
    reset so as to let errors be "seen" if they occur after the special section
    where I "expect" an error.

    tia
    Mark
     
    R. Robert Bell, Jul 27, 2004
    #2
  3. MP

    Ed Jobe Guest

    Mark,
    Here is a sample of my standard error handling. Line labels don't do
    anything, they are just the location where the GoTo goes. :) So, anything
    below the label gets executed. OnError GoTo 0 is used to reset error
    handling after you have told it to simply to ignore an errror with the
    Resume Next statement. Inside the error handler, use Err.Clear to clear the
    current error before you jump back into your procedure again.


    Sub testing()
    On Error GoTo Err_Control
    'normal procedure code goes here.

    Exit_Here:
    Exit Sub
    Err_Control:
    Select Case Err.Number
    'Add your Case selections here
    'Case Is = 1000
    'Handle error
    'Err.Clear
    'Resume Exit_Here
    Case Else
    MsgBox Err.Number & ", " & Err.Description, , "testing"
    Err.Clear
    Resume Exit_Here
    End Select
    End Sub
     
    Ed Jobe, Jul 27, 2004
    #3
  4. MP

    Ed Jobe Guest

    I forgot to mention this part. Where Case = 1000, you could substitute any
    error number that your code might cause, e.g. the error number that would be
    encountered where you would have used Resume Next, or a custom error caused
    by Err.Raise. The Case Else part handles errors not caused by your
    procedure.
     
    Ed Jobe, Jul 27, 2004
    #4
  5. MP

    Ed Jobe Guest

    I'm real forgetful today...By putting the procedure name in the title of the msgbox, I can readily tell
    where in the code the error ocurred.
     
    Ed Jobe, Jul 27, 2004
    #5
  6. MP

    MP Guest

    Thanks Ed,
    I will study and learn
    Mark

     
    MP, Jul 27, 2004
    #6
  7. MP

    MP Guest

    Thanks Robert
    This is very helpful, I will study it.
    Mark
     
    MP, Jul 27, 2004
    #7
  8. MP

    jdinardi Guest

    Mark, when it comes to GoTo you want to be careful. In structured programming languages the use of GoTo should be kept to a minimum because it can complicate and/or defeat your logic.

    From the code you posted you have a couple of spots that an error could potentially occur, which are at the calls to Utility.Get... Dependign on what you want to do I would consider putting each of them in a loop with an err handler in the loop. The Err object is great for this...

    Sub JUNK()
    On Error Resume Next
    Dim pt As Variant
    Dim obj As AcadEntity


    Do
    Err.Clear
    pt = ThisDrawing.Utility.GetPoint(, "Specify a point: ")
    Loop While Err

    Do
    Err.Clear
    ThisDrawing.Utility.GetEntity obj, pt, "Select a line: "
    If Not TypeOf obj Is AcadLine Then Err.Raise 1
    Loop While Err
    End Sub


    There are a lot of ways to approach it, as you can see here I'm using On Error Resume Next, which isn't bad but you do have to be careful as it can mask other errors, just make sure you provide proper error handling (easily done using the Err object) to exit the routine if something unexpected happens.

    If you do use GoTo and a error handler make sure you add the line:
    Exit Sub
    prior to you error handler (as Ed has done above) otherwise that code will always run at the end of your routine.

    Regards,
    Jacob Dinardi
     
    jdinardi, Jul 29, 2004
    #8
  9. MP

    MP Guest

    Thanks Jacob,
    The learning never ends!
    :)

    I have seen many references to *NOT* using GOTO as being one of the worst
    left overs from old days of basic lang.

    but i had also seen it presented as preferrable to Resume Next

    Thanks for your amplification of this process.

    in that regard, (just out of curiousity) in this line:
    "Loop While Err"
    - in my understanding (or rather lack thereof) the Err object always
    exists...
    so I assume that call is "auto-translated" by vb into
    Loop While Err.Number <> 0

    is that true????


    Mark

    programming languages the use of GoTo should be kept to a minimum because it
    can complicate and/or defeat your logic.
    potentially occur, which are at the calls to Utility.Get... Dependign on
    what you want to do I would consider putting each of them in a loop with an
    err handler in the loop. The Err object is great for this...
    Error Resume Next, which isn't bad but you do have to be careful as it can
    mask other errors, just make sure you provide proper error handling (easily
    done using the Err object) to exit the routine if something unexpected
    happens.
    always run at the end of your routine.
     
    MP, Jul 29, 2004
    #9
  10. MP

    Jürg Menzi Guest

    Hi MP

    Maybe this can be a sample how to work with 'On Error Resume Next':

    Code:
    Public Function MeGetReal() As Variant
    
    Dim RetVal As Variant
    
    On Error Resume Next
    
    With ThisDrawing.Utility
    .InitializeUserInput 6, "Select"
    RetVal = .GetReal(vbCrLf & "Please enter a value or [Select]: ")
    If Err.Number <> 0 Then
    If Err.Number = -2145320928 Then
    Err.Clear
    GetRealTest = .GetInput
    Else
    Err.Clear
    GetRealTest = vbEmpty
    End If
    Else
    GetRealTest = RetVal
    End If
    End With
    
    End Function
    
    Ceers
     
    Jürg Menzi, Jul 29, 2004
    #10
  11. MP

    Jürg Menzi Guest

    Sorry, typos...

    Code:
    Public Function MeGetReal() As Variant
    
    Dim RetVal As Variant
    
    On Error Resume Next
    
    With ThisDrawing.Utility
    .InitializeUserInput 6, "Select"
    RetVal = .GetReal(vbCrLf & "Please enter a value or [Select]: ")
    If Err.Number <> 0 Then
    If Err.Number = -2145320928 Then
    Err.Clear
    MeGetReal = .GetInput
    Else
    Err.Clear
    MeGetReal = vbEmpty
    End If
    Else
    MeGetReal = RetVal
    End If
    End With
    
    End Function
    
    Cheers
     
    Jürg Menzi, Jul 29, 2004
    #11
  12. MP

    MP Guest

    Thanks Jürg,
    I'll study that too!
    Mark
     
    MP, Jul 29, 2004
    #12
  13. MP

    jdinardi Guest

    Mark, to answer your questions regarding the Err object; most objects have a default property meaning you don't have to explicitly access it, just use the object name. For the Err object the default property is the Number property (current error number). So if you type:

    debug.print Err

    You'll actually see the current value of the Number property. Another example of this is when using text boxes; the default property of the textbox object is Text, so both of the followng give the same result.

    debug.print Text1.Text
    debug.print Text1

    Now onto using Do...While. The "While" portion of the loop continues to run the loop as long as the condition is True. You also need to know that since the While is looking for a boolean value (True/False) and the Err.Number gives a numeric value that a conversion takes place from numeric to boolean. When this happens:

    0 = False
    all other numbers = True


    So these next to statements are equivalent:

    Loop While Err
    Loop While Err <> 0 as you stated.


    Hope that sheds some light on things for you.

    Regards,
    Jacob
     
    jdinardi, Jul 30, 2004
    #13
  14. MP

    Mark Propst Guest

    Thank you Jacob,
    Right, the default property...i should have thought of that
    already...well i kind of did in the back of my mind .sort of!...whew - kind
    of musty back there...eech... :)
    That was an extremely clear explanation. Thank you.

    And thanks again to Jacob, RRBell, EdJobe, and Jurg Menzi for taking time to
    help me understand this process.
    It is much clearer now after reading everyones' tips several times and
    trying various combinations.
    Your ongoing help is much appreciated and extremely under-paid!!!
    :)

    Mark

    a default property meaning you don't have to explicitly access it, just use
    the object name. For the Err object the default property is the Number
    property (current error number). So if you type:
    example of this is when using text boxes; the default property of the
    textbox object is Text, so both of the followng give the same result.
    run the loop as long as the condition is True. You also need to know that
    since the While is looking for a boolean value (True/False) and the
    Err.Number gives a numeric value that a conversion takes place from numeric
    to boolean. When this happens:
     
    Mark Propst, Jul 30, 2004
    #14
  15. MP

    Jürg Menzi Guest

    Hi Mark

    Welcome...¦-)
    <VBG> Shall I send you my Swiss bank account number?

    Cheers
     
    Jürg Menzi, Jul 31, 2004
    #15
  16. MP

    Mark Propst Guest

    Only if you include your pin number
    :)

     
    Mark Propst, Aug 1, 2004
    #16
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.