Try/Catch Exceptionhandling

Share your advanced PureBasic knowledge/code with the community.
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Try/Catch Exceptionhandling

Post by Hroudtwolf »

Hi,

I made a few of experiments with Try/Catch possibilities in PureBasic.
Here are my provisional results.

Code: Select all

 ; 2009 (c) Hroudtwolf
; PureBasic-Lounge.com
; Windows
; PureBasic 4.x

Prototype.i pEXCEPTION_DivideByZero        ()
Prototype.i pEXCEPTION_IllegalInstruction  ()
Prototype.i pEXCEPTION_AccessViolation     ()
Prototype.i pEXCEPTION_OutOfBounds         ()
Prototype.i pEXCEPTION_Unknown             ()
Prototype.i pEXCEPTION_Throw               ( nErrorID.i )

Structure tTryCatch
    EXCEPTION_DivideByZero       .pEXCEPTION_DivideByZero
    EXCEPTION_IllegalInstruction .pEXCEPTION_IllegalInstruction
    EXCEPTION_AccessViolation    .pEXCEPTION_AccessViolation
    EXCEPTION_OutOfBounds        .pEXCEPTION_OutOfBounds
    EXCEPTION_Unknown            .pEXCEPTION_Unknown
    EXCEPTION_Throw              .pEXCEPTION_Throw
EndStructure

Declare.i TryCatchHandler ( *ptrEP.EXCEPTION_POINTERS )

Global TryCatch.tTryCatch

Macro CallException ( _EXCEPTION_ )
   If TryCatch\EXCEPTION_#_EXCEPTION_
      TryCatch\EXCEPTION_#_EXCEPTION_ ()
   EndIf
EndMacro

Procedure TryCatchHandler ( *ptrEP.EXCEPTION_POINTERS )
   Protected *ptrRec    .EXCEPTION_RECORD = *ptrEP\pExceptionRecord
   Protected *ptrContext.CONTEXT          = *ptrEP\ContextRecord

   Select *ptrRec\ExceptionCode 
      Case #EXCEPTION_FLT_DIVIDE_BY_ZERO , #EXCEPTION_INT_DIVIDE_BY_ZERO
      CallException ( DivideByZero )

      Case #EXCEPTION_ILLEGAL_INSTRUCTION
      CallException ( IllegalInstruction )

      Case #EXCEPTION_ACCESS_VIOLATION
      CallException ( AccessViolation )   
 
      Case #EXCEPTION_ARRAY_BOUNDS_EXCEEDED   
      CallException ( AccessViolation ) 
     
      Default
      CallException ( Unknown ) 
     
   EndSelect
 
   *ptrContext\eip + 1
   
   ProcedureReturn #EXCEPTION_CONTINUE_EXECUTION
EndProcedure

Macro Try
   SetUnhandledExceptionFilter_( @ TryCatchHandler () )
EndMacro

Macro EndTry
   SetUnhandledExceptionFilter_( #Null )
   TryCatch\EXCEPTION_DivideByZero        = #Null
   TryCatch\EXCEPTION_IllegalInstruction  = #Null
   TryCatch\EXCEPTION_AccessViolation     = #Null
   TryCatch\EXCEPTION_OutOfBounds         = #Null
   TryCatch\EXCEPTION_Unknown             = #Null
   TryCatch\EXCEPTION_Throw               = #Null
EndMacro

Macro Catch ( _EXCEPTION_ , _CATCHPROC_ )
   TryCatch\EXCEPTION_#_EXCEPTION_ = @ _CATCHPROC_
EndMacro

Macro Throw ( _OUTPUT_ = 0 )
   If TryCatch\EXCEPTION_Throw : TryCatch\EXCEPTION_Throw ( _OUTPUT_ ) : EndIf
EndMacro


;************************************************
;**** Testing
;************************************************
 
Procedure myCatchProc1 ()

   MessageRequester ( "Error" , "'Division by zero' error in try-block" )
   ProcedureReturn #Null
EndProcedure

Procedure myCatchProc2 ()

   MessageRequester ("Error" , "'Access Violation' error in try-block" )
   End
EndProcedure

Procedure myThrowCatch ( nErrorID.i )
   
   MessageRequester ( "Error" , "Error. Values doesn't match. " )
 
   ProcedureReturn #Null
EndProcedure

DisableDebugger

Catch ( DivideByZero , myCatchProc1 () )
Try
   b = 0
   a = 2 / b
EndTry

Catch ( Throw , myThrowCatch () )
Try
   a = 0
   b = 1
   If a <> b
      throw ()
   EndIf
EndTry

Catch ( AccessViolation , myCatchProc2 () )
Try
   !int 20
EndTry
Maybe this source is a little bit inspiration for you.

Regards
Wolf
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Post by luis »

Very interesting !

Thank you for sharing it.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

SetUnhandledExceptionFilter_() is a top-level exception filter and is not limited to the exceptions that occur within your try/catch block. Using this method in more than a single thread will create unexpected collisions. For example, one thread can captures another's error or resumable exceptions closing your program.
The SetUnhandledExceptionFilter function lets an application supersede the top-level exception handler that Win32 places at the top of
each thread and process.
I wish we had a real try/catch but this method is not an adequate replacement.
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Post by zxtunes.com »

Hroudtwolf thank you.
it that needs me. 8)

Do not I understand why is not it built-in in Purebasic? :evil:
Post Reply