ERROR TRAP

Share your advanced PureBasic knowledge/code with the community.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

ERROR TRAP

Post by BackupUser »

Code updated For 5.20+

Restored from previous forum. Originally posted by gnozal.

Code: Select all

; Found on www.pure-board.de
; Done some translation, cosmetic changes and added ErrorCode.
;
; ------------------------------------------
; WARNING
; The purebasic debugger must be disabled !
; -----------------------------------------
;
; ------------------------------------------------------------------------
; ERROR TRAP START
; ------------------------------------------------------------------------
Global CrLf.s, Tab.s
CrLf=Chr(13)+Chr(10)
Tab=Chr(9)
Global ErrorTrapVal.l
Global ErrorTrapEIP.l
#EXCEPTION_ILLEGAL_INSTRUCTION = $C000001D
#EXCEPTION_STACK_OVERFLOW = $C00000FD
;
; This procedure is called at program crash!
Procedure ErrorTrap(*lpEP.EXCEPTION_POINTERS)
  
  *cont.CONTEXT = *lpEP\ContextRecord ; 1st error description
  *rec.EXCEPTION_RECORD = *lpEP\ExceptionRecord ; 2nd error description
  ErrorCode.l = *rec\ExceptionCode ; ExceptionRecord error code
  ;
  Select ErrorCode ; Translate most common error codes
    Case #EXCEPTION_FLT_DIVIDE_BY_ZERO
      ErrorMsg.s = "DIVISION BY ZERO"
    Case #EXCEPTION_INT_DIVIDE_BY_ZERO
      ErrorMsg = "DIVISION BY ZERO"
    Case #EXCEPTION_ACCESS_VIOLATION
      ErrorMsg = "ACCESS VIOLATION"
    Case #EXCEPTION_ARRAY_BOUNDS_EXCEEDED
      ErrorMsg = "ARRAY BOUNDS EXCEEDED"
    Case #EXCEPTION_DATATYPE_MISALIGNMENT
      ErrorMsg = "DATATYPE MISALIGNMENT"
    Case #EXCEPTION_ILLEGAL_INSTRUCTION
      ErrorMsg = "ILLEGAL INSTRUCTION"
    Case #EXCEPTION_STACK_OVERFLOW
      ErrorMsg = "STACK OVERFLOW"
    Default
      ErrorMsg = "UNKNOWN!"
  EndSelect
  ;
  If ErrorTrapVal=0 ; User has not clicked on 'Ignore' yet
    DisplayErrorTrapMessage: ; Error dialog
    Title.s = "UNEXPECTED ERROR"
    Message.s = "The program crashed !" + CrLf
    Message.s + "" + CrLf
    Message.s = "Code"+Tab+": " + Str(ErrorCode) + CrLf
    Message.s + "Message"+Tab+": " + ErrorMsg + CrLf
    Message.s + "" + CrLf
    Message.s + "Register values :" + CrLf
    Message.s + "EDI"+Tab+Str(*cont\edi) + CrLf
    Message.s + "ESI"+Tab+Str(*cont\esi) + CrLf
    Message.s + "EBX"+Tab+Str(*cont\ebx) + CrLf
    Message.s + "EDX"+Tab+Str(*cont\edx) + CrLf
    Message.s + "ECX"+Tab+Str(*cont\ecx) + CrLf
    Message.s + "EAX"+Tab+Str(*cont\eax) + CrLf
    Message.s + "EBP"+Tab+Str(*cont\ebp) + CrLf
    Message.s + "EIP"+Tab+Str(*cont\eip) + CrLf
    Message.s + "ESP"+Tab+Str(*cont\esp) + CrLf
    Message.s + "" + CrLf
    Message.s + "Choose"+Tab+"'Ignore' to continue," + CrLf
    Message.s + Tab+"'Retry' to try again," + CrLf
    Message.s + Tab+"'Abort' to quit."
    Flags.l = 2 | 16 ; AbortRetryIgnore | Critical
    SelButton.l = MessageRequester(Title,Message,Flags)
    ; User selection
    If SelButton=3 ; Abort / Abandon
      ProcedureReturn 1
    ElseIf SelButton=4 ; Retry / Réessayer
      ProcedureReturn -1
    ElseIf SelButton=5 ; Ignore / Ignorer
      *cont\eip+1 ; Increment program pointer to continue after the error...
      ErrorTrapVal=1
      ErrorTrapEIP=*cont\eip
      ProcedureReturn -1
    EndIf
  Else ; User has already clicked on 'Ignore'!
    If ErrorTrapEIP <> *cont\eip ; New error ?
      Goto DisplayErrorTrapMessage ; If yes, display error dialog
    EndIf
    *cont\eip+1 ; Increment program pointer to continue after the error...
    ErrorTrapEIP=*cont\eip
    ProcedureReturn -1
  EndIf
  
EndProcedure
; Activate ErrorTrap
Procedure InitErrorTrap()
  
  SetUnhandledExceptionFilter_(@ErrorTrap())
  
EndProcedure
; Desactivate ErrorTrap
Procedure UnloadErrorTrap()
  
  SetUnhandledExceptionFilter_(0)
  
EndProcedure
; ------------------------------------------------------------------------
; ERROR TRAP END
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
; EXAMPLE
; ------------------------------------------------------------------------
InitErrorTrap()
MessageRequester("","After this dialog, there will be a division by zero!",0)
Y=0
X=999/Y
MessageRequester("","You see this dialog although a division by zero error occured!",0)
UnloadErrorTrap()