Results 1 to 32 of 32

Thread: Error Trapping in an Executable

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2018
    Posts
    486

    Error Trapping in an Executable

    Is it possible to get a MsgBox to trigger displaying an error code if an error is encountered?
    I mean in sort of global handler?

    If my app is run as executable on certain machines, it gets to a certain point then quietly exits without a word.
    The Splash Screen displays correctly, a few MsgBoxes display as they are supposed to, then app just seems to do nothing.

    I have no idea as to how to debug this.

  2. #2
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,955

    Re: Error Trapping in an Executable

    U will need to add on error everywhere.
    I think it’s possible to subclass. Or u need to check err.number each function

  3. #3
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,277

    Re: Error Trapping in an Executable

    What I do is use this routine to log the same debug messages that appear in the IDE when the executable runs. It is controlled by setting the DbgFlg when the executable is created, and should give you an idea where the problem is occurring. It can be refined further by adding Debug messages.

    J.A. Coutts
    Code:
    Public DbgFlg           As Boolean  'Determines if debug messages are recorded
    
    Public Sub PrintDebug(Msg As String)
        Debug.Print Msg
        If DbgFlg Then Call LogError(Msg)
    End Sub
    
    Public Sub LogError(Log$)
        Dim LogFile%
        LogFile% = OpenFile(App.Path + "\Socket.Log", 3, 0, 80)
        If LogFile% = 0 Then
            'MsgBox "File Error with LogFile", 16, "ABORT PROCEDURE"
            Exit Sub
        End If
        Print #LogFile%, CStr(Now) + ": " + Log$
        Close LogFile%
    End Sub

  4. #4
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Posts
    4,122

    Re: Error Trapping in an Executable

    Quote Originally Posted by mms_ View Post
    I have no idea as to how to debug this.
    Do what every professional piece of code happens to do eventually -- instrument logging error handlers in each and every routine in each and every module of your application.

    In production you want every little detail as to what's going on with your code before crashing -- not silencing failures with On Error Resume Next as many do.

    There is vbWatchdog product (google it) which can help with implementing a global error handler if your application is p-code compiled (but not native compiled).

    Edit: Another option is to use disk2vhd to snapshot the offending machine then boot it as a VM on in your local Hyper-V and install VB6 IDE and debug everything *on* it. Done that several times under dire circumstances as a final resort.

    cheers,
    </wqw>

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    8,173

    Re: Error Trapping in an Executable

    Just to say it, in VB6 code, error trapping does nest correctly. And that's true whether the error is raised from downstream VB6 code in your project, or raised by some ActiveX DLL.

    For instance, an On Error Goto Label or On Error Resume in a higher-level procedure isn't cancelled when it makes calls into lower-level procedures, even if those lower level procedures execute an On Error Goto 0.

    There's only one Err object in VB6, but I guess there's something like a reference counter on how many times On Error Goto Label (or On Error Resume Next) has been executed.

    And, all of that just makes it where you can implement error trapping in a procedure, and really not worry about what's happening downstream, handling those downstream raised errors anyway you like in your upstream procedure.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  6. #6
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Posts
    4,122

    Re: Error Trapping in an Executable

    Quote Originally Posted by Elroy View Post
    Just to say it, in VB6 code, error trapping does nest correctly.
    Mostly yes, unless you have RaiseEvent Click() in a routine in which case any error in the event handler(s) for your class/control Click event does not trap in your current error handler but the end-user gets a MsgBox and your application is closed directly with no logging etc.

    In theory it's enough to have error handlers in event handlers only i.e. Form_Load, Button_Click, etc. and Sub Main as these are top-level entry points for any VB6 event-driven application.

    But in practice you want your errors getting logged as early as possible before any caller error handler deciding to swallow the error altogether with OERN or similar.

    cheers,
    </wqw>

  7. #7
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    8,173

    Re: Error Trapping in an Executable

    Quote Originally Posted by wqweto View Post
    Mostly yes, unless you have RaiseEvent Click() in a routine in which case any error in the event handler(s) for your class/control Click event does not trap in your current error handler but the end-user gets a MsgBox and your application is closed directly with no logging etc.

    In theory it's enough to have error handlers in event handlers only i.e. Form_Load, Button_Click, etc. and Sub Main as these are top-level entry points for any VB6 event-driven application.

    But in practice you want your errors getting logged as early as possible before any caller error handler deciding to swallow the error altogether with OERN or similar.

    cheers,
    </wqw>

    Well yeah. I just consider that up to the programmer though. If they wish to run an OERN in their Sub Main, that's their decision. I suppose we could design some kind of an error logger in a Collection if we really wanted to trap them though, and just use it in places where we wanted to record our errors.

    ADDED: Actually, I just tested and an OERN in Sub Main doesn't swallow errors from loaded forms. I'm surprised by that. I guess the nesting only works while we've still got control of the thread.
    Last edited by Elroy; Jun 26th, 2022 at 11:35 AM.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  8. #8
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,955

    Re: Error Trapping in an Executable

    as I wrote, u can use subclassing, here an example:

    in a module

    Code:
    Option Explicit
    
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    Dim OldWindowProc&
    
    Sub ErrorHandler(ByVal hWnd&, Optional ByVal Start As Boolean)
        If OldWindowProc > 0 Then
            SetWindowLong hWnd, -4, OldWindowProc
            OldWindowProc = 0
            If Err.Number > 0 Then
                MsgBox "Runtime Error: " & Err.Number & vbNewLine & Err.Description, vbCritical, "Error: " & Err.HelpContext
                Err.Clear
            End If
        End If
        If Start Then OldWindowProc = SetWindowLong(hWnd, -4, AddressOf ErrorWindowProc)
    End Sub
    
    Function ErrorWindowProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Const WM_NCDESTROY = &H82
               
        If Msg = WM_NCDESTROY Then
            ErrorHandler hWnd
        Else
            ErrorWindowProc = CallWindowProc(OldWindowProc, hWnd, Msg, wParam, lParam)
        End If
        If Err.Number > 0 Then ErrorHandler hWnd, True
    End Function
    and to try it
    Code:
    Private Sub Form_Load()
        ErrorHandler Me.hWnd, True
        r = 1 / 0
    End Sub
    and if u use On Error Resume Next you will only get the errorhandler msgbox. remember to call ErrHandler Me.hWnd on UnLoad
    this is just basic. u could add a Public ID that u add in each function, and show that in the msgbox, for more information.
    u could skip msgbox and just save it in a log-file (couttsj suggested that).
    Last edited by baka; Jun 26th, 2022 at 01:30 PM.

  9. #9
    Fanatic Member
    Join Date
    Jun 2015
    Posts
    748

    Re: Error Trapping in an Executable

    You could look into setunhandledexceptionfilter api. Especially if the crash is happening outside the vb code

  10. #10
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    362

    Re: Error Trapping in an Executable

    wqweto wrote

    Do what every professional piece of code happens to do eventually -- instrument logging error handlers in each and every routine in each and every module of your application.
    Here I have my Lesson 101.

    Even if I don't practise it as a rule, at lease I could have deployed it to help diagnose the nasty problem I had just a little while ago. Just a little while I ago I had had an encounter wherein "IDE is alright throughout, but EXE may just crash".

    After a long and hard struggle I resolved the problem, Dilettante asked:
    So you found your bug but never resolved the question you raised.
    I didn't elaborate; I just confirmed that my problem was gone but my question was not answered.

    As a matter of fact, I'd never found my bug in the ordinary sense that the bug line was/should usually be highlighted by VB, because there was not such a code line in existence. Basically the entire process of my program is a loop, each iteration is to call 6 or 7 functions and after each iteration a small block of "target" pixels would be replaced with "synthesized" ones in the "source" area. "Source" is the pixels surrounding the target area - if the target is a lasso, then we have an extended lasso to include the source area. The loop may be from a couple of hundreds to over 2000, depending on the target size, the thickness the user sets of the source area and the complexity of the image (32-BPP one is usually quicker as zero alpha areas can't be a target/source). A lot of byte operations in the algorithm and the arrangements are not the ones we usually see.

    Every function and code lines are in fact fine. It is just that a particular variable in a particular function, likely through the parameters, in conjunction with one or more of other variables "might" produce a result going outside the bound which the EXE doesn't tolerate. The EXE crash didn't always occur, and when it occurred it might be on 53th iteration or another time 212th iteration -- it varied. So the real solution is not to catch a faulty code line, but to set suitable conditions to filter out any possible loopholes. But, in which function or functions should I set what conditions?

    Had I used the "logging" as wqweto mentioned, I would at least know the crash occurred in which function (I could thus concentrate on that function, rather than beating about the bush here and there).
    Last edited by Brenker; Jun 26th, 2022 at 09:35 PM.

  11. #11
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,955

    Re: Error Trapping in an Executable

    hm.
    usually a crash without knowing where is if u use a class.
    so it will only tell that the call crashed but not where inside the class
    I would change the class into a module if possible.

  12. #12
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    362

    Re: Error Trapping in an Executable

    It is in a user control. Because I allow various toolbox tools for user to select the area to be removed and filled with synthesized pixels, viz Rectangular Region, Oval Region, Polygon Region and Lasso, as well as Brush, Line and Fill, to suit different scenarios, so I placed the code pertaining to the Content-Aware Fill in the Viewport user control.

    At one time as I was so frustrated that I created a separate project for Content-Aware Fill only, I separated the code pertaining to Content-Aware Fill in a .BAS. The same result. As I said (in my thread on that subject), for over 15 years' time, I'd never been so abashed. I consider myself lucky still, as I was finally able to add appropriate conditions in a particular function to filter out possible loopholes, and since then no more EXE crash.

    BTW, I would never just for EXE crash reasons change my code from CLS to BAS, nor to uncheck "Remove Array Bounds Checks". Currently I have ICO.cls, GIF.cls, PNG.cls, JPG.cls, EMF.cls, PCX.cls, TGA.cls, ANI.cls, EXIF.cls, DIB.cls, PAL.cls, CMYK.cls, CRC.cls, RC4.cls, YCbCr.cls and TIFFtags.cls, etc. As a hobbyist I like to understand the common graphic formats on byte basis, and I don't like cut corners.
    Last edited by Brenker; Jun 27th, 2022 at 02:51 AM.

  13. #13
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,955

    Re: Error Trapping in an Executable

    my game is mostly modules. I have 2 classes. one is the direct2d engine and one is the directsound8 engine.
    and the reason is mostly because I need to initialize/destroy/restart the class. surely I can do that without a class, but so far the classes works well.

    and the only time I need to "dig" is when the crash happens inside those 2 classes (very seldom). everywhere else the IDE is giving me "where it happens"
    so I can quite easily fix any bugs.
    sure theres complex bugs, those that takes a bit before the crash happens. and those are hard to find and take more time to figure out.
    but 99% of the time I can fix it.
    I try to avoid classes as much possible. and I don't use activex/user controls at all.

    I remove everything, in the advanced optimization.

  14. #14

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2018
    Posts
    486

    Re: Error Trapping in an Executable

    Some good suggestions here, thanks all!

    couttsj
    I wanted to try your sample, but the declare I found for OpenFile takes 3 parameters
    Public Declare Function OpenFile Lib "kernel32" (ByVal lpFileName As String, lpReOpenBuff As OFSTRUCT, ByVal wStyle As Long) As Long
    Your call to this function passes 4
    LogFile% = OpenFile(App.Path + "\Socket.Log", 3, 0, 80)

    wqweto
    From the linked sample you provide I think you are telling me to add the code in red to every one of my subs and functions?
    and add the code in blue to a module?
    Code:
    Public Sub MySub()
    
        Const FUNC_NAME     As String = "MySub"
        On Error GoTo EH
        
        ' MySub code here
    
    EH:
        PrintError FUNC_NAME
    
    End Sub
    
    Private Sub PrintError(sFunction As String)
        #If USE_DEBUG_LOG <> 0 Then
            DebugLog MODULE_NAME, sFunction & "(" & Erl & ")", Err.Description & " &H" & Hex$(Err.Number), vbLogEventTypeError
        #Else
            Debug.Print "Critical error: " & Err.Description & " [" & MODULE_NAME & "." & sFunction & "]"
        #End If
    End Sub
    baka
    My app is subclassed, so I can add your provided code to my app.

  15. #15
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,277

    Re: Error Trapping in an Executable

    Quote Originally Posted by mms_ View Post
    Some good suggestions here, thanks all!

    couttsj
    I wanted to try your sample, but the declare I found for OpenFile takes 3 parameters
    Public Declare Function OpenFile Lib "kernel32" (ByVal lpFileName As String, lpReOpenBuff As OFSTRUCT, ByVal wStyle As Long) As Long
    Your call to this function passes 4
    LogFile% = OpenFile(App.Path + "\Socket.Log", 3, 0, 80)
    OpenFile is a universal routine that I use to access files. It handles all the error checking, but can be replaced with:
    Code:
      FileNum% = FreeFile
      Open FileName For Append Shared As FileNum%
    J.A. Coutts
    Code:
    Function OpenFile(FileName$, Mode%, RLock%, RecordLen%) As Integer
        Const REPLACEFILE = 1, READAFILE = 2, ADDTOFILE = 3
        Const RANDOMFILE = 4, BINARYFILE = 5
        Const NOLOCK = 0, RDLOCK = 1, WRLOCK = 2, RWLOCK = 3
        Dim ErrorCode As Long
        Dim FileNum%, Action%, LockFlg%
        LockFlg% = 0
        FileNum% = FreeFile
        On Error GoTo OpenErrors
        Select Case Mode
            Case REPLACEFILE
                Select Case RLock%
                    Case NOLOCK
                        Open FileName For Output Shared As FileNum%
                    Case RDLOCK
                        Open FileName For Output Lock Read As FileNum%
                    Case WRLOCK
                        Open FileName For Output Lock Write As FileNum%
                    Case RWLOCK
                        Open FileName For Output Lock Read Write As FileNum%
                End Select
            Case READAFILE
                Select Case RLock%
                    Case NOLOCK
                        Open FileName For Input Shared As FileNum%
                    Case RDLOCK
                        Open FileName For Input Lock Read As FileNum%
                    Case WRLOCK
                        Open FileName For Input Lock Write As FileNum%
                    Case RWLOCK
                        Open FileName For Input Lock Read Write As FileNum%
                End Select
            Case ADDTOFILE
                Select Case RLock%
                    Case NOLOCK
                        Open FileName For Append Shared As FileNum%
                    Case RDLOCK
                        Open FileName For Append Lock Read As FileNum%
                    Case WRLOCK
                        Open FileName For Append Lock Write As FileNum%
                    Case RWLOCK
                        Open FileName For Append Lock Read Write As FileNum%
                End Select
            Case RANDOMFILE
                Select Case RLock%
                    Case NOLOCK
                        Open FileName For Random Shared As FileNum% Len = RecordLen%
                    Case RDLOCK
                        Open FileName For Random Lock Read As FileNum% Len = RecordLen%
                    Case WRLOCK
                        Open FileName For Random Lock Write As FileNum% Len = RecordLen%
                    Case RWLOCK
                        Open FileName For Random Lock Read Write As FileNum% Len = RecordLen%
                End Select
            Case BINARYFILE
                Select Case RLock%
                    Case NOLOCK
                        Open FileName For Binary Shared As FileNum%
                    Case RDLOCK
                        Open FileName For Binary Lock Read As FileNum%
                    Case WRLOCK
                        Open FileName For Binary Lock Write As FileNum%
                    Case RWLOCK
                        Open FileName For Binary Lock Read Write As FileNum%
                End Select
            Case Else
              Exit Function
        End Select
        OpenFile = FileNum%
        Exit Function
    OpenErrors:
        If Err = 70 Then  'File is locked, try 3 times
            LockFlg% = LockFlg% + 1
            Debug.Print "File Locked!"
            If LockFlg > 3 Then GoTo OpenErrCont
            Resume
        End If
    OpenErrCont:
        ErrorCode = Err
        Action% = FileErrors(ErrorCode)
        Select Case Action%
            Case 0
              Resume            'Resumes at line where ERROR occured
            Case 1
                Resume Next     'Resumes at line after ERROR
            Case 2
                OpenFile = 0     'Unrecoverable ERROR-reports error, exits function with error code
                Exit Function
            Case Else
                'MsgBox Error$(Err) + vbCrLf + "After line " + Str$(Erl) + vbCrLf + "Program will TERMINATE!"
                'Unrecognized ERROR-reports error and terminates.
                Call LogAccess("Error|after|line|Str$(Erl)!")
                End
        End Select
    End Function
    
    Function FileErrors(errVal As Long) As Integer
        Dim Msg$, MsgType%, Response%
    'Return Value 0=Resume,              1=Resume Next,
    '             2=Unrecoverable Error, 3=Unrecognized Error
    MsgType% = 48
    Select Case errVal
        Case 68
          Msg$ = "That device appears Unavailable."
          MsgType% = MsgType% + 4
        Case 71
          Msg$ = "Insert a Disk in the Drive"
        Case 53
          Msg$ = "Cannot Find File"
          MsgType% = MsgType% + 5
       Case 57
          Msg$ = "Internal Disk Error."
          MsgType% = MsgType% + 4
        Case 61
          Msg$ = "Disk is Full.  Continue?"
          MsgType% = 35
        Case 64, 52
          Msg$ = "That Filename is Illegal!"
        Case 70
          Msg$ = "File in use by another user!"
          MsgType% = MsgType% + 5
        Case 76
          Msg$ = "Path does not Exist!"
          MsgType% = MsgType% + 2
        Case 54
          Msg$ = "Bad File Mode!"
        Case 55
          Msg$ = "File is Already Open."
        Case 62
          Msg$ = "Read Attempt Past End of File."
        Case Else
          FileErrors = 3
          Exit Function
      End Select
      FileErrors = 2
    End Function

  16. #16

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2018
    Posts
    486

    Re: Error Trapping in an Executable

    Thank you couttsj
    I will need your LogAccess function for me to be able to try this out.

  17. #17
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,277

    Re: Error Trapping in an Executable

    Quote Originally Posted by mms_ View Post
    Thank you couttsj
    I will need your LogAccess function for me to be able to try this out.
    Forget that line. Comment it out and activate the Msgbox line above it. I copied that routine from a service program that does not permit any interaction with the screen.

    J.A. Coutts

  18. #18

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2018
    Posts
    486

    Re: Error Trapping in an Executable

    OK thanks, everything works.

    Just to make sure I'm understanding correct usage as intended.
    I would sprinkle throughout my code indicating milestones that successfully completed as below?
    Code:
    Option Explicit
    
    Private Sub Form_Load()
        DbgFlg = True
    End Sub
    
    Private Sub Command1_Click()
        ' < CODE BLOCK A>
        PrintDebug ("CODE BLOCK A completed successfully")
        ' < CODE BLOCK B>
        PrintDebug ("CODE BLOCK B completed successfully")
        ' < CODE BLOCK C>
        PrintDebug ("CODE BLOCK C completed successfully")
        ' < CODE BLOCK D>
        PrintDebug ("CODE BLOCK D completed successfully")
    End Sub

  19. #19
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,277

    Re: Error Trapping in an Executable

    Quote Originally Posted by mms_ View Post
    OK thanks, everything works.

    Just to make sure I'm understanding correct usage as intended.
    I would sprinkle throughout my code indicating milestones that successfully completed as below?
    Code:
    Option Explicit
    
    Private Sub Form_Load()
        DbgFlg = True
    End Sub
    
    Private Sub Command1_Click()
        ' < CODE BLOCK A>
        PrintDebug ("CODE BLOCK A completed successfully")
        ' < CODE BLOCK B>
        PrintDebug ("CODE BLOCK B completed successfully")
        ' < CODE BLOCK C>
        PrintDebug ("CODE BLOCK C completed successfully")
        ' < CODE BLOCK D>
        PrintDebug ("CODE BLOCK D completed successfully")
    End Sub
    That will work. What I do is convert and Debug.Print lines to PrintDebug. Then it works in the IDE as well as the executable.

    J.A. Coutts

  20. #20

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2018
    Posts
    486

    Re: Error Trapping in an Executable

    OK thanks, but now I am confused...
    Your code with my implementation above works in both IDE and as exe

  21. #21
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,277

    Re: Error Trapping in an Executable

    Quote Originally Posted by mms_ View Post
    OK thanks, but now I am confused...
    Your code with my implementation above works in both IDE and as exe
    That's the whole idea. You send all debug statements to the PrintDebug routine. Without the DbgFlg set, all Debug.Print statements function in the IDE as normal. In the executable, Debug.Print statements do not execute, but if the DbgFlg is set, those messages log to file. The DbgFlg is only used to troubleshoot the executable. Once the problem is located and resolved, it would be removed.

    J.A. Coutts

  22. #22

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2018
    Posts
    486

    Re: Error Trapping in an Executable

    So I am using your debug routine correctly then.

    One more question.
    In looking at your code, there appears to be more than just the logging of various milestones in the text file,
    but also some error code reporting.
    I tried with a divide by 0 zero error, but no error is reported.
    Am I misunderstanding what was supposed to happen?
    Code:
    Private Sub Command1_Click()
        ' < CODE BLOCK A>
        PrintDebug ("CODE BLOCK A completed successfully")
        ' < CODE BLOCK B>
        PrintDebug ("CODE BLOCK B completed successfully")
        ' < CODE BLOCK C>
        MsgBox "Try to divide by 0 " & 1 / 0
        PrintDebug ("CODE BLOCK C completed successfully")
        ' < CODE BLOCK D>
        PrintDebug ("CODE BLOCK D completed successfully")
    End Sub

  23. #23
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,955

    Re: Error Trapping in an Executable

    the "best" way seems to be to add in all your fuctions:

    Sub/Function BlaBla()
    On Error Goto TErr
    - code -
    Exit Sub/Function
    TErr: ErrHandler Number/String
    End Sub/Function

    or

    On Error Goto TErr
    ErrId = 101
    - code -
    ErrId = 102
    - code -
    ErrId = 103
    - code -
    Exit Sub/Function
    TErr: ErrHandler ErrId

    if the sub/function has a lot of code and u want to check specific lines
    its a lot of work since u need to add that to all your functions/subs.

  24. #24
    Fanatic Member
    Join Date
    Jun 2015
    Posts
    748

    Re: Error Trapping in an Executable

    You can add line numbers to each line and use erl()

    Code:
    Private Sub Form_Load()
        On Error GoTo hell
        Dim a As Long
    7734  a = "nope"
    hell: MsgBox Erl() & " n1"
    End Sub
    Last edited by dz32; Jun 27th, 2022 at 06:16 PM.

  25. #25
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,277

    Re: Error Trapping in an Executable

    Quote Originally Posted by mms_ View Post
    So I am using your debug routine correctly then.

    One more question.
    In looking at your code, there appears to be more than just the logging of various milestones in the text file,
    but also some error code reporting.
    I tried with a divide by 0 zero error, but no error is reported.
    Am I misunderstanding what was supposed to happen?
    It is not an error trapping routine. PrintDebug only reports what you tell it to report. Assuming you use PrintDebug in the IDE to provide information as you progress through your program, that same information will appear in the log file when the DbgFlg is set.

    J.A. Coutts

  26. #26
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    362

    Re: Error Trapping in an Executable

    I also had a "quietly exits without a word" encounter last year, similar to what mms_ is now experiencing.

    I have an "Animated PNG" form and an "Animated GIF Editor" form which are invoked from a MDI, with "vbModal". I had been using the 14-MB EXE for many years on Vista, Win 7/8 and Win 10 alright. Sometime last year I found that when I clicked "Exit" to close any of the said vbModal forms, not only the form closed, but MDI as well. Because it occurred only on Exit, so I only needed to check Sub Class_Terminate() - this was fairly easy.

    I placed MsgBox "here 1", MsgBox "here 2" and MsgBox "here 3", etc at certain points in Sub Class_Terminate(), as a cheap but effective way to catch the culprit code block (e.g. if I didn't have a chance to acnowledge MsgBox "here 3", the problem must be between "2" and "3"). Below is the culprit code block I caught:

    Code:
        'If m_FrameCount > 0 Then
        '     For i = 1 To m_FrameCount
        '            'This line will cause crash under Windows 10 in 2021
        '           'If Not (m_FrameImage(i).frDIB.hDIB = 0) Then
        '                Set m_FrameImage(i).frDIB = Nothing
        '           'End If
        '           ......
        '     Next i
        'End If
    frDIBs are used to store the individual frame images read from the animated PNG/GIF file. In the earlier years of Win 10, the code had been alright, but after a certain Win 10 update last year it became a killer code - causing the EXE "quietly exits without a word". I'd no idea which Win 10 update caused the trouble. Anyway, I commented out the code lines, and the EXE is fine again.
    Last edited by Brenker; Jun 28th, 2022 at 07:21 PM.

  27. #27
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Posts
    4,122

    Re: Error Trapping in an Executable

    It was a certain Win 10 update which *revealed* the problem.

    I mean the dormant issue must have been there all along but did not cause any issues with previous OS versions.

    cheers,
    </wqw>

  28. #28
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,955

    Re: Error Trapping in an Executable

    yeah. its interesting how things changes with OS.
    new bugs appears, or reveals.
    even so they have done a great job making VB6 applications survive that long and still works for the most part.

    I also use msgbox when I can't find whats going on.
    usually when using classes.

    so, I break with a msgbox until I find where,
    after that I dig deeper into that class and do the same there if its not obvious.
    and most of the time is a silly bug that was created because I changed something else elsewhere that affected it.

    for my current project, 90% of the time is a Subscript out of range.
    since I have a huge UDT with thousands of properties and I share my build all the time to my writer partner, there could be a file missing or not updated.
    so its good to have error trapping so if any error occurs, he gets a msgbox telling: saving data.

    for myself, that works directly with IDE and have everything up to date, and I don't care about saving data, I don't really need any error trapping.
    if something happens, I fix it.
    usually an error is because we are adding stuff, and when u do, of course a bug or two can occur.

    for the player, he can just report the default error message, since that usually is enough information for me to know where to look.
    I want errors to popup, so I can fix it.

    so for me error trapping is:
    - something that I can not control, API or typelib calling something external that need error trapping
    - to protect data that we don't want to get lost, so the error trapping is calling a saving-function before it quits.

    otherwise I don't see any need for it.
    the error trapping will not protect you from future OS updates.
    but in another thread we had this discussion, if the application has many different commands, u could say that if at least some works, its a success so we want error trapping.
    and I agree there. in those cases it can be good to have. but not in a program that is doing 1 thing.

  29. #29
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    33,923

    Re: Error Trapping in an Executable

    Quote Originally Posted by baka View Post
    yeah. its interesting how things changes with OS.
    new bugs appears, or reveals.
    even so they have done a great job making VB6 applications survive that long and still works for the most part.
    Isn't that the definition of an upgrade: Take out old bugs, insert new ones.

    Quote Originally Posted by baka View Post
    I also use msgbox when I can't find whats going on.
    usually when using classes.

    so, I break with a msgbox until I find where,
    after that I dig deeper into that class and do the same there if its not obvious.
    and most of the time is a silly bug that was created because I changed something else elsewhere that affected it.
    Be careful adding msgboxes... that can actually change the flow of how things execute. I had a case back in the day where somehting wasn't working, so I added msgboxes .... and then it worked... took them out... stopped working ... it was a weird situation. Strangely enough, the "solution" ended up being commenting out the message boxes... It's among the strangest things I've ever encountered.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  30. #30
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,955

    Re: Error Trapping in an Executable

    well, the msgbox are added to find the crash.

    so

    1
    2
    3
    4 crash
    5

    if I dont know that 4 will cause a crash I add

    1
    msgbox "1"
    2
    msgbox "2"
    etc

    so if I see 2 I know the crash happened in 3, so I can investigate 3.
    so of course the msgbox will get removed once the bug is revealed.

    I had a similar situation.
    the program didn't work. got a crash to something that shouldn't
    so I added some garbage like
    a = 1
    and it worked.

    so something messed up really bad.

    I know that "not not" is one of the things that can mess up and create strange bugs.
    so there should be more that can do that as well.

    I also know that if I compile my project in windows 10 I can get "other bugs" that I don't get if I compile in windows 7
    (I use the same VB6). so it seems the compiler is doing differently in windows 10

  31. #31
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    33,923

    Re: Error Trapping in an Executable

    I know that the msgboxes are for finding the error ... I'm just saying be careful in using them like that because it can change behaviour unexpectedly. Personally I've moved from that to more innocuous means, such as file logging or printing out to the terminal/console.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  32. #32
    Addicted Member
    Join Date
    Jul 2002
    Location
    new zealand (kiwi)!
    Posts
    202

    Re: Error Trapping in an Executable

    I have used 'mztools' add-in tool for many years to automatically put in error trapping template code
    into every important sub/function.
    If you use the tool to also add line numbers, then the trapping code template can include something like:
    msgbox "Program Error " & Err.Number & Err.Descripton & "at line " & Erl
    to isolate the error line.
    Saved me hours of debug, many times...
    It also has lots of other useful stuff, such as toggling / searching bookmarks.

    -don

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width