My latest attempt at "Global" Error Handling

ErrorHandler.inc
Code:
'*** ErrorHandling.inc
'***      Written by: Cliff Nichols - 08-28-2008
'***      Modified by: Cliff Nichols - 06-28-2009
'***
'***      Compilers Tested:   8.04/9.0/9.01
'***      Should work on:     7/8/9
'***
'***      OS'es Tested:       XP-Pro SP3, Vista-Ultimate
'***      Should work on:     95/98/ME/NT/2K/XP/Vista
'***
'***      Purpose - Beefed up Error Handling Routines to attempt to "Bullet-Proof" apps
'***                Via a "GLOBAL ERROR HANDLER" (Which in theory does not exist)
'***      Concepts:
'***                Demonstrate PB Errors - (How each either sets or raises an error window)
'***                Demonstrate Windows Errors - (How each either sets or raises an error window)
'***                Demonstrate GPF "EXCEPTIONS" - (The errors you see with the cryptic
'***                                                   "Had a problem and has to close" for an explaination
'***                                                   , but no plain english why the error?)
'***
'***      Special Thnx:
'***                Paul Dixon - Without whom, I would not have found out about EIP's and beginning to understand
'***                               how to decipher assembly code (still learning so this INC is not complete...YET!!!! that is)
'--------------------------------------------------------------------------------
'*** Now for the FUN Stuff
'***      PB has 'On Error' for handling errors on the DDT side
'***           PB (DDT) can set an error with ERR = some number (does not raise an error, just sets the value)
'***           PB (DDT) can raise an error just by ERROR = some number
'***           PB (DDT) can test an error state by checking the value of ERR
'***           PB appears to work with 'On Error' for handling errors on the SDK side for most errors
'***      Windows uses Exceptions (But you must handle, or ignore to not generate a GPF)       '<--- This statement may not be TOTALLY correct, but still is concise
'***           Windows (SDK) can set an error with 'SetLastError (does not raise an error, just sets the value)
'***           Windows (SDK) can set an error with parameters using 'SetLastErrorEX (does not raise an error, just sets the value)
'***           Windows (SDK) can raise an error with 'RaiseException' api call
'***           Windows (SDK) can test an error state by 'GetLastError'
'***
'***      Windows has "Exceptions" (You've seen them...the default usually shows the typical "*.exe has encountered a problem and needs to close" message)
'***           Windows "Exceptions" can be raised, but default handler is typically fatal, but you can override that fatality
'***
'***      PB narrowing down to line that caused the error
'***           Manually inserting Line Numbers can definitely nail down an error, but either needs to be done by hand, or pre-compile to do it for you
'*** ---> Scratch that thought, I now have figured out using a macro that I call "DebugLine" can be used on the same line as code, or a separate line
'*** ---> to "Land-Mark" by inserting a line number in your code at compile time (Disperce anywhere you think you want a landmark to home in on an error)
'***
'***           PB Line numbers (if inserted) can assist in locating where an error occured (larger projects its smarter to contain line numbers to their functions)
'***           PB FUNCNAME$ in conjunction with the line numbers can nail down what line the error occured on
'***
'***      Windows narrowing down to line that caused the error
'***           Extended Instruction Pointer (EIP)      --->      to be worked on and detailed later
'***      Conjunction, junction, whats your function??? :-)
'***
'*** Out of the ordinary ideas:
'***      No Globals - Use functions to store value of "Global" and look up the value when needed        '<--- Not 100% on this yet, but no problems either
'***      Locating lines of code - Figuring out what line of readable code I am on, from the machine code that I read
'***                               (only beginning, so take at face value, and please correct me where I am wrong)
'***      Macro's - Usually I have no use for them, because if I use the same code in multiple functions,
'***                     then I just write a function to be called from each function.
'***                     But in a case like this where variables are only valid locally,
'***                     I can see using macros to replace my code at compile time can save a ton a space
'***                     and be more readable in the future
'***
'***
'--------------------------------------------------------------------------------

'*** If not already declared in your code, then declare this INC
#IF NOT %DEF(%ERRORHANDLING)
     %ERRORHANDLING = 1
'*** Globals
'***      NONE
'*** OverRideError flag can be one of the following values:
'***      %UNKNOWN_VALUE = Unknown until user input at run-time
'***      %NORESUME = Do not resume
'***      %RESUME = Resume at same line of code that caused the error.
'***                (Error must be corrected or will result in an infinite loop)
'***      %RESUMENEXT = Resume at line after code that caused the error.
'***      %CRASH = Purposely allow a Crash (GPF) to happen.
'***
     %UNKNOWN_VALUE = -1                                                                  'Unknown for when I do not know the value until runtime
'*** <--- I chose RESUMENEXT to be 0 if for the odd chance that a flag is not set (default is 0) that I do NOT cause an infinite loop
     %RESUME = 1                                                                          'Use 1 to resume (this is so that if left out, then not stuck in an infinite loop)
     %RESUMENEXT = 0                                                                      'Use 0 for Resume Next in case flag is not set to avoid infinite loops
     %NORESUME = -1                                                                       'NoResume = UnKnown so that code decides what is best path to follow
     %CRASH = %INVALID_HANDLE_VALUE                                                       'Purposely allow crash of App
'*** Constants not found in Win32Api.Inc (Have to be re-researched because I found %EXCEPTION_ILLEGAL_INSTRUCTION = %STATUS_ILLEGAL_INSTRUCTION
'     %EXCEPTION_ILLEGAL_INSTRUCTION  = &HC000001D
     %EXCEPTION_ILLEGAL_INSTRUCTION = %STATUS_ILLEGAL_INSTRUCTION
     %EXCEPTION_STACK_OVERFLOW       = &HC00000FD
     %EXCEPTION_INVALID_DISPOSITION  = &HC0000026
     %EXCEPTION_NONCONTINUABLE_EXCEPTION = &HC0000025
'*** Type to hold my settings
TYPE ErrorCodes
     lpEP AS EXCEPTION_POINTERS PTR                                                       'Windows EXCEPTIONS (Errors)
     SafePointer AS LONG                                                                  'Pointer value to ErrHandler
     ErrorLogNumber AS LONG                                                               'Handle to log file
     LogError AS LONG                                                                     'If logging errors
     PbErrorValue AS LONG                                                                 'PB ERR
     WinErrorValue AS LONG                                                                'GetLastError
     AppErrorValue AS LONG                                                                'Error value reguardless of PB Error or Windows Error
     PbErrorDesc AS ASCIIZ * %MAX_PATH                                                    'PB Description of Error in plain english
     WinErrorDesc AS ASCIIZ * %MAX_PATH                                                   'Windows Description of Error in plain english
     AppErrorDesc AS ASCIIZ * %MAX_PATH                                                   'Application Specific Description of Error
     CodeModule AS ASCIIZ * %MAX_PATH                                                     'Function that caused the error         '<--- MOST Important thing I have always been after in larger projects)
     LineLabelNumber AS ASCIIZ * %MAX_PATH                                                'Line number (or Variable) that was last passed before the error
     OverRideError AS LONG                                                                'Variable for if to continue even if there is an error
     StringValue AS ASCIIZ * %MAX_PATH                                                    'Error value as a string
     Desc AS ASCIIZ * %MAX_PATH                                                           'Description for loggin purposes to help track down a problem
END TYPE

'*** Declare Functions

'*************************************************************************************************************
'*** Macro's - When Compiled, replace the name of the macro with all the functions and processes in the macro
'***           As if you had done it yourself in each and every SUB/FUNCTION it was called
'***           Do not add line numbers to Macro's unless you want to renumber functions that use the macros
'*************************************************************************************************************
'*** Using SetUnhandledExceptionFilter you can over-ride the default error handler for windows
'***      SetUnhandledExceptionFilter %NULL                           = Default handling within UnhandledExceptionFilter
'***      SetUnhandledExceptionFilter %EXCEPTION_EXECUTE_HANDLER      = Return from UnhandledExceptionFilter and execute the associated exception handler.
'***                                                                       (Usually results in process termination.)
'***      SetUnhandledExceptionFilter %EXCEPTION_CONTINUE_EXECUTION   = Return from UnhandledExceptionFilter and continue execution from the point of the exception.
'***                                                                       Note that the filter function is free to modify the continuation state by modifying the exception information supplied through its LPEXCEPTION_POINTERS parameter
'***      SetUnhandledExceptionFilter %EXCEPTION_CONTINUE_SEARCH      = Proceed with normal execution of UnhandledExceptionFilter . That means obeying the SetErrorMod flags, or invoking the Application Error pop-up message box.
'***


'*** OnError - Replacement for "ON ERROR"  (Place as 1st line of code in your function)
     MACRO OnError
          ON ERROR GOTO ErrHandler                                                        'PB command for On Error
          LOCAL lpEP AS EXCEPTION_POINTERS                                                'If Windows Crops up an error
          LOCAL ErrFunc AS LONG                                                           'If Error within my function
          LOCAL SoftwarePathName AS ASCIIZ * %MAX_PATH
          LOCAL ErrorLogNumber AS LONG
          LOCAL ErrorCode AS ErrorCodes
          LOCAL Continuable AS LONG
          LOCAL LinesOfCodeToSkip AS LONG
          LOCAL DebugLineNumber AS STRING
          SetGetSafeJump CODEPTR(ErrHandler), ErrorCode.SafePointer, %True                'Set flag for escaping functions that I can not find a way to continue from
'          SetGetJumpLines 1, LinesOfCodeToSkip, %TRUE                                     'Set flag for how many lines of code to skip (default = 1 line)
          SetUnhandledExceptionFilter( CODEPTR (ExceptionHandler))                        'Over-Ride Windows default and let me decide if a FATAL error or to 'Fix-And-Continue'
          SetGetErrorCodes VARPTR(ErrorCode), %UNKNOWN_VALUE, %TRUE                       'Set a handle to ErrorCodes without using GLOBALS      '<--- Not 100% on this yet
          GetModuleFileName(GetModuleHandle(BYVAL %NULL), SoftwarePathName, %MAX_PATH)    'Get Parent PathName and Name
          SoftwarePathName = MID$(SoftwarePathName, INSTR(-1, SoftwarePathName,"\") + 1)  'Path Name
          SoftwarePathName = MID$(SoftwarePathName, 1, INSTR(SoftwarePathName,".") - 1)   'Strip the .Dll or .Exe
          SetGetLogErrors %UNKNOWN_VALUE, ErrorCode.LogError, %UNKNOWN_VALUE              'Get flag for logging errors
          SELECT CASE ErrorCode.LogError
               CASE %FALSE
               CASE %TRUE
                    SetGetLogFileNumber(%UNKNOWN_VALUE, ErrorCode.ErrorLogNumber, %UNKNOWN_VALUE)
                    SELECT CASE ErrorCode.ErrorLogNumber
                         CASE 0         'No file yet
                              ErrorCode.ErrorLogNumber = FREEFILE
                              OPEN SoftwarePathName + " Error Log.txt" FOR APPEND LOCK SHARED AS #ErrorCode.ErrorLogNumber          'Open the log file
                              SetGetLogFileNumber(ErrorCode.ErrorLogNumber, ErrorCode.ErrorLogNumber, %TRUE)
                    END SELECT
          END SELECT
     END MACRO

     MACRO DebugLine
          DebugLineNumber = TRIM$(STR$(VAL(DebugLineNumber) + 1))
          ErrorCode.LineLabelNumber = DebugLineNumber
     END MACRO

'*** HandleErrors - (Place as last line in your function)
     MACRO HandleErrors
          SetGetLogErrors %UNKNOWN_VALUE, ErrorCode.LogError, %UNKNOWN_VALUE         'Get flag for logging errors
          SELECT CASE ErrorCode.LogError
               CASE %TRUE
               CASE %FALSE
                    CLOSE ErrorCode.ErrorLogNumber                                                            'End log file
                    SetGetLogFileNumber(0, ErrorCode.ErrorLogNumber, %TRUE)
          END SELECT
          EXIT MACRO                                                                      'Exit (do not care if sub/function/method/property
     ErrHandler:                                                                          'Only gets here if an error
'*** The following Error Information has to stay in the macro due to the error is cleared when it leaves the function that it was raised in.
          ErrorCode.PbErrorValue = ERR                                                    'Get PB Last Error
          ErrorCode.WinErrorValue = GetLastError                                          'Get API Last Error
          ExceptionInfo(ErrorCode)                                                        'Fill Information for logging
          SELECT CASE ErrorCode.OverRideError                                             'Decide how to continue
               CASE %UNKNOWN_VALUE
                    Continuable = MSGBOX("Error: " + STR$(ErrorCode.AppErrorValue) + SPACE$(5) + "Desc: " + ErrorCode.AppErrorDesc + $CR _
                                        + " Function: " + SPACE$(5) + CALLSTK$(1) + $CR + $CR + "Ignore this error?", %MB_ICONERROR OR %MB_YESNO, FUNCNAME$ + SPACE$(5) + "Windows Error")
                    SELECT CASE Continuable
                         CASE %IDYES
                              RESUME NEXT
                         CASE %IDNO
                    END SELECT
               CASE %NORESUME                                                             'Just let default handlers decide what to do
               CASE %RESUME                                                               '<-- NOT recommended unless code added to correct how we got here in the 1st place
                    RESUME
               CASE %RESUMENEXT                                                           'Resume code at next line of code
                    RESUME NEXT
          END SELECT
     END MACRO

'******* Test functions to remove the need for GLOBALS, buy calling a function and Set or Get the value *******
     FUNCTION SetGetErrorCodes(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
          STATIC FunctionValue AS LONG                                                    'Static to hold current value
          SELECT CASE ResetValue                                                          'Decide whether to Set or to Get the current value
               CASE %False, %UNKNOWN_VALUE                                                'If set to False, or -1 Then Get Current Value
                    ValueResults = FunctionValue                                          'Return Results as a parameter
               CASE = %TRUE                                                               'If set to True then Reset the Current Value
                    FunctionValue = ValueToSet                                            'Reset the value
                    ValueResults = FunctionValue                                          'Return Results as a parameter
          END SELECT
          FUNCTION = %False                                                               'Return if Function Failed
     END FUNCTION

     FUNCTION SetGetLogErrors(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
          STATIC FunctionValue AS LONG                                                    'Static to hold current value
          SELECT CASE ResetValue                                                          'Decide whether to Set or to Get the current value
               CASE %False, %UNKNOWN_VALUE                                                'If set to False, or -1 Then Get Current Value
                    ValueResults = FunctionValue                                          'Return Results as a parameter
               CASE = %TRUE                                                               'If set to True then Reset the Current Value
                    FunctionValue = ValueToSet                                            'Reset the value
                    ValueResults = FunctionValue                                          'Return Results as a parameter
          END SELECT
          FUNCTION = %False                                                               'Return if Function Failed
     END FUNCTION

     FUNCTION SetGetLogFileNumber(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
          STATIC FunctionValue AS LONG                                                    'Static to hold current value
          SELECT CASE ResetValue                                                          'Decide whether to Set or to Get the current value
               CASE %False, %UNKNOWN_VALUE                                                'If set to False, or -1 Then Get Current Value
                    ValueResults = FunctionValue                                          'Return Results as a parameter
               CASE = %TRUE                                                               'If set to True then Reset the Current Value
                    FunctionValue = ValueToSet                                            'Reset the value
                    ValueResults = FunctionValue                                          'Return Results as a parameter
          END SELECT
          FUNCTION = %False                                                               'Return if Function Failed
     END FUNCTION

     FUNCTION SetGetSafeJump(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
          STATIC FunctionValue AS LONG                                                    'Static to hold current value
          SELECT CASE ResetValue                                                          'Decide whether to Set or to Get the current value
               CASE %False, %UNKNOWN_VALUE                                                'If set to False, or -1 Then Get Current Value
                    ValueResults = FunctionValue                                          'Return Results as a parameter
               CASE = %TRUE                                                               'If set to True then Reset the Current Value
                    FunctionValue = ValueToSet                                            'Reset the value
                    ValueResults = FunctionValue                                          'Return Results as a parameter
          END SELECT
          FUNCTION = %False                                                               'Return if Function Failed
     END FUNCTION
'--------------------------------------------------------------------------------
'*** Now for the DOOZYYYYyyyy....Handling GPF's and other major fatal errors
'--------------------------------------------------------------------------------
'*************************************************************************************************************
'*** ExceptionInfo is information that can be caught by 'ON ERROR' type of errors
'*************************************************************************************************************
     FUNCTION ExceptionInfo(BYREF ErrorCode AS ErrorCodes) AS LONG
          STATIC TerminateInProcess AS LONG                                               'In case an error occurs while in the midst of ending my app
          LOCAL SafeReturnPoint AS LONG
'*** Get the PB and Windows Error Descriptions (not caring which caused the error)
          ErrorCode.PbErrorDesc = ERROR$(ErrorCode.PbErrorValue)                          'Set the PB Error Description
          FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, ErrorCode.WinErrorValue, %NULL, ErrorCode.WinErrorDesc, SIZEOF(ErrorCode.WinErrorDesc), BYVAL %NULL     'Format the Windows Error Description
          ErrorCode.AppErrorDesc = ""                                                     'Clear the Application Specific Description
          ErrorCode.CodeModule = CALLSTK$(2)                                              'Figure out what function was the 'bad puppy' that caused the error
'*** Revision check for if capable of logging the line Number that the error occurred on, or not
          SELECT CASE ErrorCode.LineLabelNumber
               CASE ""
                    SELECT CASE %PB_REVISION
                         CASE > = &H900
                              ErrorCode.LineLabelNumber = ERL$
                         CASE < &H900
                              ErrorCode.LineLabelNumber = ""
                    END SELECT
               CASE ELSE
          END SELECT
'*** Check if logging errors (Commented out TRACE commands until fixed)
          SELECT CASE ErrorCode.LogError
               CASE %FALSE
               CASE %TRUE
                    TRACE ON
                    ErrorCode.Desc = ""
                    ErrorCode.Desc = "Error PB = " + TRIM$(STR$(ErrorCode.PbErrorValue))
                    ErrorCode.Desc = ErrorCode.Desc + SPACE$(5)
                    ErrorCode.Desc = ErrorCode.Desc + "Desc = " + ErrorCode.PbErrorDesc
                    REPLACE $CR WITH "" IN ErrorCode.Desc
                    IF ErrorCode.LogError THEN PRINT# ErrorCode.ErrorLogNumber, ErrorCode.Desc
                    ErrorCode.Desc = ""
                    ErrorCode.Desc = "Error Windows = " + TRIM$(STR$(ErrorCode.WinErrorValue))
                    ErrorCode.Desc = ErrorCode.Desc + SPACE$(5)
                    ErrorCode.Desc = ErrorCode.Desc + "Desc = " + ErrorCode.WinErrorDesc
                    REPLACE $CR WITH "" IN ErrorCode.Desc
                    IF ErrorCode.LogError THEN PRINT# ErrorCode.ErrorLogNumber, ErrorCode.Desc
                    SELECT CASE ErrorCode.PbErrorValue
                         CASE 0
                              SELECT CASE ErrorCode.WinErrorValue
                                   CASE 0
                                        ErrorCode.AppErrorValue = 0
                                        ErrorCode.AppErrorDesc = "The operation completed successfully
                                   CASE ELSE
                                        ErrorCode.AppErrorValue = ErrorCode.WinErrorValue
                                        ErrorCode.AppErrorDesc = ErrorCode.WinErrorDesc
                              END SELECT
                         CASE ELSE
                              ErrorCode.AppErrorValue = ErrorCode.PbErrorValue
                              ErrorCode.AppErrorDesc = ErrorCode.PbErrorDesc
                    END SELECT
                    ErrorCode.Desc = ""
                    ErrorCode.Desc = "Error App = " + TRIM$(STR$(ErrorCode.AppErrorValue))
                    ErrorCode.Desc = ErrorCode.Desc + SPACE$(5)
                    ErrorCode.Desc = ErrorCode.Desc + "Desc = " + ErrorCode.AppErrorDesc
                    REPLACE $CR WITH "" IN ErrorCode.Desc
                    'TRACE PRINT ErrorCode.Desc
                    IF ErrorCode.LogError THEN PRINT# ErrorCode.ErrorLogNumber, ErrorCode.Desc
                    ErrorCode.Desc = ""
                    ErrorCode.Desc = ErrorCode.Desc + SPACE$(5)
                    SELECT CASE ErrorCode.LineLabelNumber
                         CASE ""
                              ErrorCode.Desc = ErrorCode.Desc + " Function: " + SPACE$(5) + ErrorCode.CodeModule
                         CASE ELSE
                              ErrorCode.Desc = ErrorCode.Desc + " Function: " + SPACE$(5) + ErrorCode.CodeModule + SPACE$(5) + "at Mile-Marker:" + SPACE$(5) + ErrorCode.LineLabelNumber +  $CRLF
                    END SELECT
                    REPLACE $CR WITH "" IN ErrorCode.Desc
                    REPLACE $LF WITH "" IN ErrorCode.Desc
                    IF ErrorCode.LogError THEN PRINT# ErrorCode.ErrorLogNumber, ErrorCode.Desc
          END SELECT
          IF ErrorCode.LogError THEN PRINT# ErrorCode.ErrorLogNumber, $CRLF
     END FUNCTION

'*************************************************************************************************************
'*** ExceptionHandler is MUCH more difficult. (and Difficult to understand the documentation)
'*************************************************************************************************************
'*** <--- MEGA-IMPORTANT!!!!
'***      According to http://www.debuginfo.com/articles/debugfilters.html
'***      Custom filters for unhandled exceptions are not called at all when the application is running under debugger.
'***      So this will not be called if using debugger
'***
'*************************************************************************************************************
     FUNCTION ExceptionHandler(BYREF lpEP AS EXCEPTION_POINTERS) AS LONG
          STATIC TerminateInProcess AS LONG
          LOCAL ErrorRecord AS EXCEPTION_RECORD POINTER
          LOCAL ErrorCode AS ErrorCodes POINTER
          LOCAL TempErrorCode AS LONG
          LOCAL Continuable AS LONG
          STATIC MostRecentError AS LONG
          LOCAL i AS LONG
          SetGetErrorCodes TempErrorCode, TempErrorCode, %UNKNOWN_VALUE                   'Since Windows NEEDS 'lpEP AS EXCEPTION_POINTERS' and only accepts 1 parameter, I had to find a work-around to Exceptions only wanting Exception Pointers
          ErrorCode = TempErrorCode
          SELECT CASE @ErrorCode.LineLabelNumber
               CASE ""
                    SELECT CASE %PB_REVISION
                         CASE > = &H900
                              @ErrorCode.LineLabelNumber = ERL$
                         CASE < &H900
                              @ErrorCode.LineLabelNumber = ""
                    END SELECT
               CASE ELSE
          END SELECT
          @ErrorCode.lpEP = VARPTR(lpEP)
          SELECT CASE TerminateInProcess                                                  'If App is unloading and a Error appears          '<--- To be developed later
               CASE %TRUE
               CASE %FALSE                                                                'If App is unloading and a Error appears          '<--- To be developed later
                    SELECT CASE @[email protected]                         'What Error caused me?
                         CASE 0
                         CASE ELSE
                              ErrorRecord = @[email protected]             'Detect the actual exception record
                              SELECT CASE @ErrorRecord.pExceptionRecord                   '<--- Array out of bounds if not checked for null pointer first
                                   CASE 0
                                   CASE ELSE
                                        DO UNTIL @ErrorRecord.pExceptionRecord = 0        'Gather the exception record(s)
                                             CALL MoveMemory(@ErrorRecord, @ErrorRecord.pExceptionRecord, SIZEOF(ErrorRecord))
                                        LOOP
                              END SELECT
'*** Alert the log to 'FATAL' Errors that could occur
                              @ErrorCode.Desc = ""
                              SELECT CASE @ErrorRecord.ExceptionCode
                                   CASE 0              'No Error
                                        @ErrorCode.StringValue = "%NO_ERROR"
                                             @ErrorCode.Desc = @ErrorCode.Desc  _
                                                            + "Error Windows = " + @ErrorCode.StringValue _
                                                             + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                            + $CRLF + SPACE$(5) _
                                                            + " Desc = " + "The operation completed successfully"
                                   CASE %EXCEPTION_ACCESS_VIOLATION
                                        @ErrorCode.StringValue =  "%EXCEPTION_ACCESS_VIOLATION"
                                        @ErrorCode.Desc = @ErrorCode.Desc _
                                                       + "Error Windows = " + @ErrorCode.StringValue  _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5)
                                                       SELECT CASE @ErrorRecord.ExceptionInformation(0)
                                                            CASE 0
                                                                 @ErrorCode.Desc = @ErrorCode.Desc + " Desc = " + "The thread tried to READ from virtual address" _
                                                                 + STR$(@ErrorRecord.ExceptionInformation(1)) + " for which it does not have the appropriate access"
                                                            CASE 1
                                                                 @ErrorCode.Desc = @ErrorCode.Desc + " Desc = " + "The thread tried to WRITE to virtual address" _
                                                                 + STR$(@ErrorRecord.ExceptionInformation(1)) + " for which it does not have the appropriate access"
                                                            CASE 8
                                                                 @ErrorCode.Desc = @ErrorCode.Desc + " Desc = " + "The thread tried to cause a user-mode data execution prevention (DEP) violation at virtual address" _
                                                                 + STR$(@ErrorRecord.ExceptionInformation(1))
                                                       END SELECT
                                   CASE %EXCEPTION_ARRAY_BOUNDS_EXCEEDED
                                        @ErrorCode.StringValue = "%EXCEPTION_ARRAY_BOUNDS_EXCEEDED"
                                        @ErrorCode.Desc = @ErrorCode.Desc  _
                                                       + "Error Windows = " + @ErrorCode.StringValue  _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking."
                                   CASE %EXCEPTION_BREAKPOINT
                                        @ErrorCode.StringValue = "%EXCEPTION_BREAKPOINT"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "A breakpoint was encountered."
                                   CASE %EXCEPTION_DATATYPE_MISALIGNMENT
                                        @ErrorCode.StringValue = "%EXCEPTION_DATATYPE_MISALIGNMENT"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The thread tried to READ or WRITE data that is misaligned on hardware that does not provide alignment." _
                                                                      + "For example, 16-bit values must be aligned on 2-byte boundaries"
                                   CASE %EXCEPTION_FLT_DENORMAL_OPERAND
                                        @ErrorCode.StringValue = "%EXCEPTION_FLT_DENORMAL_OPERAND"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "One of the operands in a floating-point operation is denormal." _
                                                                      + "A denormal value is one that is too small to represent as a standard floating-point value."
                                   CASE %EXCEPTION_FLT_DIVIDE_BY_ZERO
                                        @ErrorCode.StringValue = "%EXCEPTION_FLT_DIVIDE_BY_ZERO"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The thread tried to divide a floating-point value by a floating-point divisor of zero."
                                   CASE %EXCEPTION_FLT_INEXACT_RESULT
                                        @ErrorCode.StringValue = "%EXCEPTION_FLT_INEXACT_RESULT"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The result of a floating-point operation cannot be represented exactly as a decimal fraction."
                                   CASE %EXCEPTION_FLT_INVALID_OPERATION
                                        @ErrorCode.StringValue = "%EXCEPTION_FLT_INVALID_OPERATION"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "This exception represents any floating-point exception not included in this list."
                                   CASE %EXCEPTION_FLT_OVERFLOW
                                        @ErrorCode.StringValue = "%EXCEPTION_FLT_OVERFLOW"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type."
                                   CASE %EXCEPTION_FLT_STACK_CHECK
                                        @ErrorCode.StringValue = "%EXCEPTION_FLT_STACK_CHECK"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The stack overflowed or underflowed as the result of a floating-point operation."
                                   CASE %EXCEPTION_FLT_UNDERFLOW
                                        @ErrorCode.StringValue = "%EXCEPTION_FLT_UNDERFLOW"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type."
                                   CASE %EXCEPTION_ILLEGAL_INSTRUCTION
                                        @ErrorCode.StringValue = "%EXCEPTION_ILLEGAL_INSTRUCTION"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The thread tried to execute an invalid instruction."
                                   CASE %EXCEPTION_IN_PAGE_ERROR
                                        @ErrorCode.StringValue =  "%EXCEPTION_IN_PAGE_ERROR"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " +  @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5)
                                                       SELECT CASE @ErrorRecord.ExceptionInformation(0)
                                                            CASE 0
                                                                 @ErrorCode.Desc = @ErrorCode.Desc + " Desc = " + "The thread tried to READ from virtual address" _
                                                                 + STR$(@ErrorRecord.ExceptionInformation(1)) + " for which it does not have the appropriate access" _
                                                                 + $CRLF + "NTSTATUS = " + STR$(@ErrorRecord.ExceptionInformation(2))
                                                            CASE 1
                                                                 @ErrorCode.Desc = @ErrorCode.Desc + " Desc = " + "The thread tried to WRITE to virtual address" _
                                                                 + STR$(@ErrorRecord.ExceptionInformation(1)) + " for which it does not have the appropriate access" _
                                                                 + $CRLF + "NTSTATUS = " + STR$(@ErrorRecord.ExceptionInformation(2))
                                                            CASE 8
                                                                 @ErrorCode.Desc = @ErrorCode.Desc + " Desc = " + "The thread tried to cause a user-mode data execution prevention (DEP) violation at virtual address" _
                                                                 + STR$(@ErrorRecord.ExceptionInformation(1)) _
                                                                 + $CRLF + "NTSTATUS = " + STR$(@ErrorRecord.ExceptionInformation(2))
                                                       END SELECT
                                   CASE %EXCEPTION_INT_DIVIDE_BY_ZERO
                                        @ErrorCode.StringValue = "%EXCEPTION_INT_DIVIDE_BY_ZERO"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The thread tried to divide an integer value by an integer divisor of zero."
                                   CASE %EXCEPTION_INT_OVERFLOW
                                        @ErrorCode.StringValue = "%EXCEPTION_INT_OVERFLOW"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The result of an integer operation caused a carry out of the most significant bit of the result."
                                   CASE %EXCEPTION_INVALID_DISPOSITION
                                        @ErrorCode.StringValue =  "%EXCEPTION_INVALID_DISPOSITION"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "An exception handler returned an invalid disposition to the exception dispatcher. " _
                                                                      + "Programmers using a high-level language such as C should never encounter this exception."
                                   CASE %EXCEPTION_NONCONTINUABLE_EXCEPTION
                                        @ErrorCode.StringValue =  "%EXCEPTION_NONCONTINUABLE_EXCEPTION"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The thread tried to continue execution after a noncontinuable exception occurred."
                                   CASE %EXCEPTION_PRIV_INSTRUCTION
                                        @ErrorCode.StringValue =  "%EXCEPTION_PRIV_INSTRUCTION"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The thread tried to execute an instruction whose operation is not allowed in the current machine mode."
                                   CASE %EXCEPTION_SINGLE_STEP
                                        @ErrorCode.StringValue = "%EXCEPTION_SINGLE_STEP"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "A trace trap or other single-instruction mechanism signaled that one instruction has been executed."
                                   CASE %EXCEPTION_STACK_OVERFLOW
                                        @ErrorCode.StringValue = "%EXCEPTION_STACK_OVERFLOW"
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue   _
                                                        + " (" + STR$(@ErrorRecord.ExceptionCode) + ") "_
                                                       + $CRLF + SPACE$(5) _
                                                       + " Desc = " + "The thread used up its stack."
                                   CASE ELSE
                                        @ErrorCode.StringValue = "%Unhandled Error: "
                                        @ErrorCode.Desc = @ErrorCode.Desc   _
                                                       + "Error Windows = " + @ErrorCode.StringValue + STR$(@ErrorRecord.ExceptionCode)
                                   END SELECT
'                                   'TRACE PRINT ErrorCode.Desc
                                   IF @ErrorCode.LogError THEN PRINT# @ErrorCode.ErrorLogNumber, @ErrorCode.Desc
                                   SELECT CASE @ErrorCode.LineLabelNumber
                                        CASE ""
                                             IF @ErrorCode.LogError THEN PRINT# @ErrorCode.ErrorLogNumber, SPACE$(5) + "Function: " + SPACE$(5) + CALLSTK$(2)
                                        CASE ELSE
                                             PRINT# @ErrorCode.ErrorLogNumber, "Function: " + SPACE$(5) + CALLSTK$(2) + SPACE$(5) + "at Mile-Marker:" + SPACE$(5) + @ErrorCode.LineLabelNumber +  $CRLF
                                   END SELECT
                                   @ErrorCode.Desc = "CallStack at Error" + $CRLF
                                   FOR i = CALLSTKCOUNT TO 1 STEP -1
                                        @ErrorCode.Desc = @ErrorCode.Desc + SPACE$(5) + CALLSTK$(i) + $CRLF
                                   NEXT i
                                   IF @ErrorCode.LogError THEN PRINT# @ErrorCode.ErrorLogNumber, @ErrorCode.Desc
                                   IF @ErrorCode.LogError THEN PRINT# @ErrorCode.ErrorLogNumber, $CRLF
                         END SELECT
'*** Code for writing a crash-log, save opened documents etc...
'*** In My case, this is where I decide whether to continue, or exit
'>>> 1st attempt to RESUME NEXT I thought would be the following line to Resume Execution after the Exception
'>>>      [email protected] = [email protected] + SIZEOF([email protected])
'>>> Lo and Behold thanx to Paul Dixon's Post at http://www.powerbasic.com/support/pbforums/showthread.php?t=40575#post315530
'>>> Led me to his post in the source code forum at http://www.powerbasic.com/support/pbforums/showthread.php?t=37821
'>>> Although it is for PBCC and using Assembly code,
'>>> I did some hunting and pecking and figured out that [email protected] = [email protected] + SIZEOF([email protected])
'>>> Is the flag I need to set to 'Resume Next' (or any address I wish to jump to
                         SELECT CASE @ErrorCode.OverRideError
                              CASE %RESUME
                                   FUNCTION = %EXCEPTION_CONTINUE_EXECUTION               'Ignore the Error and continue
                              CASE %RESUMENEXT
                                   SELECT CASE IsBadCodePtr([email protected] + 1)      'SIZEOF([email protected])
                                        CASE 0              'Not an error
                                             [email protected] = [email protected] + 1
                                             FUNCTION = %EXCEPTION_CONTINUE_EXECUTION               'Ignore the Error and continue (Probably CRASH)
                                        CASE ELSE
                                             SELECT CASE IsBadCodePtr([email protected])
                                                  CASE 0
                                                       FUNCTION = %EXCEPTION_CONTINUE_EXECUTION               'Ignore the Error and continue (Probably CRASH)
                                                  CASE ELSE
                                                       FUNCTION = %EXCEPTION_EXECUTE_HANDLER                  'See if another handler can fix, or crash anyways
                                             END SELECT
                                   END SELECT
                              CASE %UNKNOWN_VALUE                                         'Decide what to do after an error
                                   Continuable = MSGBOX("Fatal Error " + SPACE$(5) + @ErrorCode.StringValue + SPACE$(5) + "(" + STR$(@ErrorRecord.ExceptionCode) + ")" _
                                                  + $CR + "Function: " + SPACE$(5) + CALLSTK$(2) + $CR + $CR + "Ignore this error?", %MB_ICONERROR OR %MB_YESNO, FUNCNAME$ + SPACE$(5) + "Windows Error")
                                   SELECT CASE Continuable
                                        CASE %IDYES
'**************************************** TEMPORARY TILL NEXT VERSION ****************************************
LOCAL SafeJumpPoint AS LONG
SetGetSafeJump(%UNKNOWN_VALUE, SafeJumpPoint, %UNKNOWN_VALUE)
[email protected] = SafeJumpPoint
FUNCTION = %EXCEPTION_CONTINUE_EXECUTION               'Ignore the Error and continue (Probably CRASH)
EXIT FUNCTION
'*************************************************************************************************************
                                             FUNCTION = %EXCEPTION_CONTINUE_EXECUTION               'Ignore the Error and continue (Probably CRASH)
                                        CASE %IDNO
                                             FUNCTION = %EXCEPTION_EXECUTE_HANDLER
                                   END SELECT
                              CASE %NORESUME                                              'Let Windows handle the error
                                   FUNCTION = %EXCEPTION_EXECUTE_HANDLER
                              CASE %CRASH
                                   FUNCTION = %EXCEPTION_CONTINUE_SEARCH                  'Similar to Let Windows handle the error, but if Windows can fix it, it will and then continue
                         END SELECT
                         MostRecentError = @ErrorRecord.ExceptionCode
               END SELECT
     END FUNCTION
#ENDIF
DemoErrorHandling.bas
Code:
#DEBUG ERROR ON                                                                           'Set Compiler flag to not forgive me for errors like "Array out of Bounds"
#COMPILE EXE                                                                              'Compile as executable
#DIM ALL                                                                                  'Declare EVERYTHING!!! (do not let me get away with anything)
#INCLUDE "Win32Api.inc"                                                                   'Include WinApi
#INCLUDE "ErrorHandling.inc"                                                              'Include ErrorHandling

'*** DECLARES (because I want to know everything is declared and I did not miss something
DECLARE FUNCTION WINMAIN(BYVAL hInstance AS DWORD, BYVAL hPrevInst AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
DECLARE FUNCTION DemoErrors ALIAS "DemoErrors"() AS LONG

'*** Functions
FUNCTION WINMAIN(BYVAL hInstance AS DWORD, BYVAL hPrevInst AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
     DemoErrors
END FUNCTION

FUNCTION DemoErrors ALIAS "DemoErrors"() EXPORT AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging                                                                              'Macro to turn on Error Handling / Logging
     SetGetLogErrors %TRUE, ErrorCode.LogError, %TRUE                                     'Set flag for logging errors
'*** PowerBasic Errors
     DemoPbError                                                                          'Demo how PB Set Error code does not necessarily "RAISE" an Error Code
     DemoRaisePbError                                                                     'Demo how PB will "RAISE" an Error Code
'*** Windows Errors
     DemoWinError                                                                         'Demo how Windows Set Error code does not necessarily "RAISE" an Error Code
'*** Windows EXCEPTION ERRORS (The almighty "Windows has encountered an error in your app and has to close")
     DemoRaiseWinError                                                                    'Demo how Windows will "RAISE" an Error Code
'*** Array Out of Bounds
     DemoArrayOutOfBounds                                                                 'Demo Array Out Of Bounds
'*** UnderFlow (registers used for the calculation cannot hold the value)
     DemoUnderflow                                                                        'Demo "UnderFlow" (value too small for your data types)
'*** OverFlow (Division by Zero)
     DemoOverflowDivisionByZero                                                           'Demo "OverFlow" (divide by zero) errors
'*** CRASH!!!! (GPF)
     DemoGPF                                                                              'Demo the typical "Had an Error and has to close" that we are all aware of
MSGBOX "Program Complete"                                                                 'Should NEVER get here because of GPF
     SetGetLogErrors %FALSE, ErrorCode.LogError, %TRUE                                    'Set flag for logging errors
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION

'*** PB ERR    -    Error flag is set, but error is NOT raised,
'***                So you have to check the value of ERR to see if there was an error
FUNCTION DemoPbError()AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + FUNCNAME$ + SPACE$(5) + STRING$(40, "-")
DebugLine                                                                                 'Maro to insert line number (Disperce anywhere you think you want a landmark to home in on an error)
     ERR = 69                                                                             'Set Error Code (Error is not raised)
     PRINT# ErrorCode.ErrorLogNumber, STRING$(3, "*") + " <--- " + "ERR does NOT raise an error, it just sets a flag" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + "END " + FUNCNAME$ + SPACE$(5) + STRING$(40, "-") + $CRLF + $CRLF
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION

'*** PB ERROR  -    Error flag is set, and error is raised,
FUNCTION DemoRaisePbError()AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging
     ErrorCode.OverRideError = %UNKNOWN_VALUE
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + FUNCNAME$ + SPACE$(5) + STRING$(40, "-")
DebugLine
     ERROR 69                                                                             'Set Error Code (Error is raised, jump to error handler)
     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "ERROR raises an error, and sets a flag" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + "END " + FUNCNAME$ + SPACE$(5) + STRING$(40, "-") + $CRLF + $CRLF
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION

FUNCTION DemoWinError()AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging
     ErrorCode.OverRideError = %RESUMENEXT
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + FUNCNAME$ + SPACE$(5) + STRING$(40, "-")
DebugLine                                                                                 'Maro to insert line number (Disperce anywhere you think you want a landmark to home in on an error)
     SetLastError 5
     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "SetLastError does NOT raise an error, it just merely setting a flag" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     SetLastErrorEx(69, %SLE_MINORERROR)
     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "SetLastErrorEx does NOT raise an error, it just merely setting a flag" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + "END " + FUNCNAME$ + SPACE$(5) + STRING$(40, "-") + $CRLF + $CRLF
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION

FUNCTION DemoRaiseWinError()AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging
     ErrorCode.OverRideError = %RESUMENEXT
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + FUNCNAME$ + SPACE$(5) + STRING$(40, "-")
DebugLine
     RaiseException %NULL, %NULL, %NULL, %NULL                                            'Bogus Fatal Error for Demo (or not fatal since I have control)
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "Continued from 1st error that was raised" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
'*** Did this twice just to show how you can continue after a Crash (GPF)
DebugLine
     RaiseException %EXCEPTION_ACCESS_VIOLATION, %NULL, %NULL, %NULL                      'Bogus Fatal Error for Demo (or not fatal since I have control)
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "Continued from 2nd error that was raised" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + "END " + FUNCNAME$ + SPACE$(5) + STRING$(40, "-") + $CRLF + $CRLF
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION

FUNCTION DemoArrayOutOfBounds()AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging
     ErrorCode.OverRideError = %UNKNOWN_VALUE
     DIM MyArrayOutOfBounds(0) AS LONG
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + FUNCNAME$ + SPACE$(5) + STRING$(40, "-")
DebugLine
     MyArrayOutOfBounds(1) = 5
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "Continued from 1st error that was raised" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
DebugLine
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + "END " + FUNCNAME$ + SPACE$(5) + STRING$(40, "-") + $CRLF + $CRLF
DebugLine
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION

FUNCTION DemoOverflowDivisionByZero()AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging
     SetGetLogErrors %UNKNOWN_VALUE, ErrorCode.LogError, %UNKNOWN_VALUE                   'Get flag for logging errors
     ErrorCode.OverRideError = %UNKNOWN_VALUE                                             'Continue after an error?        '<--- Do NOTTTTT change this to %RESUME or you will be stuck in a logging loop
     LOCAL MyOverFlow AS LONG
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + FUNCNAME$ + SPACE$(5) + STRING$(40, "-")
     MyOverFlow = 4 \ 0
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "MyOverFlow = 4 \ 0 Results in Pb protecting me (no error)" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     LOCAL a,b,c AS LONG
     LOCAL x,y,z AS CURRENCY
DebugLine                                                                                 'Maro to insert line number (Disperce anywhere you think you want a landmark to home in on an error)
     x=0.0
     y=1.0
     z=y/x                                                                                'Floating Point Division (/) by zero, I am protected by PB
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "Floating Point DivByZero: z = y/x Results in PB protecting me (no error)" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     PRINT# ErrorCode.ErrorLogNumber, $LF
     a=0
     b=1
     c=b\a                                                                                'Integer Division (\) by zero (error)          '<--- To be investigated
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "Integer DivByZero: c = b\a Results in allowing an error" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + "END " + FUNCNAME$ + SPACE$(5) + STRING$(40, "-") + $CRLF + $CRLF
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION

FUNCTION DemoUnderflow()AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging
     SetGetLogErrors %UNKNOWN_VALUE, ErrorCode.LogError, %UNKNOWN_VALUE                   'Get flag for logging errors
     ErrorCode.OverRideError = %UNKNOWN_VALUE                                             'Continue after an error?        '<--- Do NOTTTTT change this to %RESUME or you will be stuck in a logging loop
     LOCAL B AS BYTE
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + FUNCNAME$ + SPACE$(5) + STRING$(40, "-")
     DO WHILE B  < 256
          B = B + 1
          IF B + 1 = 256 THEN EXIT DO
     LOOP
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "B + 1 to overflow, PB protecting me (no error)" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     B = 255 + 1
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "B + 1 to overflow, PB protecting me (no error)" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
DebugLine     PRINT# ErrorCode.ErrorLogNumber,      STRING$(3, "*") + " <--- " + "B = 255 + 1 to overflow, PB protecting me (no error)" + " ---> "+ STRING$(3, "*")     'Notes to print to Log File
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + "END " + FUNCNAME$ + SPACE$(5) + STRING$(40, "-") + $CRLF + $CRLF
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION

FUNCTION DemoGPF()AS LONG
     OnError                                                                              'Macro to turn on Error Handling / Logging
     SetGetLogErrors %UNKNOWN_VALUE, ErrorCode.LogError, %UNKNOWN_VALUE                   'Get flag for logging errors
'*** Let Windows Crash
     MSGBOX "I will now perform a fatal error, and not recover from it", %MB_ICONINFORMATION, "Fatal Error"
     ErrorCode.OverRideError = %CRASH
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + FUNCNAME$ + SPACE$(5) + STRING$(40, "-")
     RaiseException %NULL, %NULL, %NULL, %NULL                                            'Bogus Fatal Error for Demo (or not fatal since I have control)
     PRINT# ErrorCode.ErrorLogNumber, "I continued from a crash"                          'Should never get here
     PRINT# ErrorCode.ErrorLogNumber, STRING$(40, "-") + SPACE$(5) + "END " + FUNCNAME$ + SPACE$(5) + STRING$(40, "-") + $CRLF + $CRLF
     HandleErrors                                                                         'Macro to turn off Error Handling / Logging
END FUNCTION
Just keep ignoring the errors that are created in the demo, and check out the log created for each of those errors.

Discussion can be found here