NoHandlerError.st
author Claus Gittinger <cg@exept.de>
Tue, 03 Feb 2004 16:45:01 +0100
changeset 7866 6624a55c7dd0
parent 7586 63e4900c8931
child 8399 2c311d438f2c
permissions -rw-r--r--
resourceDirectory

"
 COPYRIGHT (c) 1999 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"



"{ Package: 'stx:libbasic' }"

GenericException subclass:#NoHandlerError
	instanceVariableNames:''
	classVariableNames:'EmergencyHandler'
	poolDictionaries:''
	category:'Kernel-Exceptions-Errors'
!

!NoHandlerError class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1999 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"


!

documentation
"
    NoHandlerError is raised, if there is no exception handler
    or default action for an exception.

    The parameter is the unhandled exception.

    [Class variables:]
        EmergencyHandler <Block>    this block is evaluated, if no handler was defined
                                    for a signal (i.e. this one is responsible for the
                                    unhandled exception debugger).
                                    Having this being a block allows to globally catch
                                    these errors - even when no enclosing handler-scope
                                    around the erronous code exists.
                                    (as the catch/through does).


    [see also:]
        GenericException 
        (``Exception handling and signals'': programming/exceptions.html)
"


!

examples
"
    The emergencyHandler stuff is very useful, to prevent endUser applications
    from entering the debugger.

    Some commonly used (useful) emergency handlers are provided in the
    'useful handlers' section; try them to learn more
    (especially, the mailingHandler is fun).

    Of course, these are only examples - you may define your own handler
    block and pass it to the #emergencyHandler: method.

    BTW: the Launchers 'source & debugger' settings menu allows you
         to install either a default or the notifying handler.


    A handler which shows a box, then aborts - (no more debuggers):
                                                                [exBegin]
        NoHandlerError emergencyHandler:(NoHandlerError abortingEmergencyHandler)
                                                                [exEnd]


    A handler which aborts - (no box, no debugger):
                                                                [exBegin]
        NoHandlerError emergencyHandler:[:ex | AbortSignal raise]
                                                                [exEnd]


    try some exception (for demonstration, in some other process):
                                                                [exBegin]
        [
            #(1 2 3) at:4
        ] fork.
                                                                [exEnd]

    cleanup (switch back to the regular handler, which enters the debugger):
                                                                [exBegin]
        NoHandlerError emergencyHandler:nil
                                                                [exEnd]


    A handler which shows a warnBox and asks for debugging:
                                                                [exBegin]
        NoHandlerError emergencyHandler:(NoHandlerError notifyingEmergencyHandler)
                                                                [exEnd]



    A handler which dumps information to a file (watch the file 'errorTrace.stx'):
                                                                [exBegin]
        NoHandlerError emergencyHandler:(NoHandlerError dumpingEmergencyHandler)
                                                                [exEnd]



    A handler which sends you mail:
                                                                [exBegin]
        NoHandlerError emergencyHandler:(NoHandlerError mailingEmergencyHandler)
                                                                [exEnd]
"

! !

!NoHandlerError class methodsFor:'initialization'!

initialize

    NotifierString := 'unhandled exception'.

    "
     self initialize
    "


! !

!NoHandlerError class methodsFor:'emergency handlers'!

emergencyHandler
    "return the handler used for unhandled exceptions.

     If no EmergencyHandler has been set, a handler which enters the 
     debugger is returned.
     The debugger is opened by asking the signal for a debug action,
     this allows to provide other debuggers in specialized (subclass-instances)
     of Signal (if that is ever needed)"

    "
     set it up, when called the first time
    "
    EmergencyHandler isNil ifTrue:[
        EmergencyHandler := [:ex |
            "
             sending it to the signal allows per-signal specific
             debuggers to be implemented in the future
             (for example, segv in primitive code could show things 
              on the C-level ..)
            "
            (ex signal) openDebuggerOnException:ex.
            "/ if we arrive here, the debugger proceeded.
            "/ the value below is the exceptions value ...
            nil
        ]
    ].

    ^ EmergencyHandler


!

emergencyHandler:aOneArgBlock
    "set the handler used for unhandled exceptions.
     The default (a nil-handler) leads to a debugger to be shown."

    EmergencyHandler := aOneArgBlock

    "ST-80 behavior of first showing a notifier:
     (I prefer to get right into the debugger, though)

     Exception
        emergencyHandler:
            [:ex | self errorNotify:ex errorString ]
    "

    "ST-X behavior of going right into the debugger:

     Exception
        emergencyHandler:nil
    "

    "automatically aborting current operation, on error:
     (may be useful for end-user apps; make certain, 
      you have abortSignal handlers at appropriate places)

     Exception
        emergencyHandler:
            [:ex | Object abortSignal raise. ex return. ]
    "

    "finally, traditional language system behavior; dump core ;-)

     Exception
        emergencyHandler:
            [:ex | Smalltalk exitWithCoreDump. ]
    "

    "Modified: 15.1.1997 / 20:49:06 / cg"

! !

!NoHandlerError methodsFor:'default actions'!

defaultAction
    "This action is performed, if nobody handles the NoHandlerError.
     Look for either a per-process emergencyHandlerBlock 
     or the global emergencyHandler (from Exception) ..."

    |block|

    Processor notNil ifTrue:[ 
        "care for signal during startup (Processor not yet created)"
        block := Processor activeProcess emergencySignalHandler.
    ].
    block isNil ifTrue:[
        block := self class emergencyHandler.
        block isNil ifTrue:[
            "care for error during startup (Exception not yet initialized)"
            ^ MiniDebugger 
                enterWithMessage:self description 
                mayProceed:self mayProceed
        ].
    ].

    ^ block value:self

!

noHandler
    "redefined to avoid recursive invocations"

    ^ self
! !

!NoHandlerError methodsFor:'queries'!

mayProceed
    "return true, if the exception handler is allowed to proceed
     the execution where the exception occured."

    parameter isNil ifTrue:[^ true].
    ^ parameter mayProceed


! !

!NoHandlerError class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic/NoHandlerError.st,v 1.9 2003-08-29 19:15:06 cg Exp $'
! !

NoHandlerError initialize!