3 , ForeignFunctionInterface
4 , ExistentialQuantification
6 #ifdef __GLASGOW_HASKELL__
7 {-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}
12 -----------------------------------------------------------------------------
14 -- Module : Control.OldException
15 -- Copyright : (c) The University of Glasgow 2001
16 -- License : BSD-style (see the file libraries/base/LICENSE)
18 -- Maintainer : libraries@haskell.org
19 -- Stability : experimental
20 -- Portability : non-portable (extended exceptions)
22 -- This module provides support for raising and catching both built-in
23 -- and user-defined exceptions.
25 -- In addition to exceptions thrown by 'IO' operations, exceptions may
26 -- be thrown by pure code (imprecise exceptions) or by external events
27 -- (asynchronous exceptions), but may only be caught in the 'IO' monad.
28 -- For more details, see:
30 -- * /A semantics for imprecise exceptions/, by Simon Peyton Jones,
31 -- Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson,
34 -- * /Asynchronous exceptions in Haskell/, by Simon Marlow, Simon Peyton
35 -- Jones, Andy Moran and John Reppy, in /PLDI'01/.
37 -----------------------------------------------------------------------------
39 module Control.OldException {-# DEPRECATED "Future versions of base will not support the old exceptions style. Please switch to extensible exceptions." #-} (
41 -- * The Exception type
42 Exception(..), -- instance Eq, Ord, Show, Typeable
43 New.IOException, -- instance Eq, Ord, Show, Typeable
44 New.ArithException(..), -- instance Eq, Ord, Show, Typeable
45 New.ArrayException(..), -- instance Eq, Ord, Show, Typeable
46 New.AsyncException(..), -- instance Eq, Ord, Show, Typeable
48 -- * Throwing exceptions
49 throwIO, -- :: Exception -> IO a
50 throw, -- :: Exception -> a
51 ioError, -- :: IOError -> IO a
52 #ifdef __GLASGOW_HASKELL__
53 -- XXX Need to restrict the type of this:
54 New.throwTo, -- :: ThreadId -> Exception -> a
57 -- * Catching Exceptions
59 -- |There are several functions for catching and examining
60 -- exceptions; all of them may only be used from within the
63 -- ** The @catch@ functions
64 catch, -- :: IO a -> (Exception -> IO a) -> IO a
65 catchJust, -- :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
67 -- ** The @handle@ functions
68 handle, -- :: (Exception -> IO a) -> IO a -> IO a
69 handleJust,-- :: (Exception -> Maybe b) -> (b -> IO a) -> IO a -> IO a
71 -- ** The @try@ functions
72 try, -- :: IO a -> IO (Either Exception a)
73 tryJust, -- :: (Exception -> Maybe b) -> a -> IO (Either b a)
75 -- ** The @evaluate@ function
76 evaluate, -- :: a -> IO a
78 -- ** The @mapException@ function
79 mapException, -- :: (Exception -> Exception) -> a -> a
81 -- ** Exception predicates
85 ioErrors, -- :: Exception -> Maybe IOError
86 arithExceptions, -- :: Exception -> Maybe ArithException
87 errorCalls, -- :: Exception -> Maybe String
88 dynExceptions, -- :: Exception -> Maybe Dynamic
89 assertions, -- :: Exception -> Maybe String
90 asyncExceptions, -- :: Exception -> Maybe AsyncException
91 userErrors, -- :: Exception -> Maybe String
93 -- * Dynamic exceptions
96 throwDyn, -- :: Typeable ex => ex -> b
97 #ifdef __GLASGOW_HASKELL__
98 throwDynTo, -- :: Typeable ex => ThreadId -> ex -> b
100 catchDyn, -- :: Typeable ex => IO a -> (ex -> IO a) -> IO a
102 -- * Asynchronous Exceptions
106 -- ** Asynchronous exception control
108 -- |The following two functions allow a thread to control delivery of
109 -- asynchronous exceptions during a critical region.
111 block, -- :: IO a -> IO a
112 unblock, -- :: IO a -> IO a
114 -- *** Applying @block@ to an exception handler
118 -- *** Interruptible operations
124 assert, -- :: Bool -> a -> a
128 bracket, -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
129 bracket_, -- :: IO a -> IO b -> IO c -> IO ()
132 finally, -- :: IO a -> IO b -> IO a
134 #ifdef __GLASGOW_HASKELL__
135 setUncaughtExceptionHandler, -- :: (Exception -> IO ()) -> IO ()
136 getUncaughtExceptionHandler -- :: IO (Exception -> IO ())
140 #ifdef __GLASGOW_HASKELL__
143 -- import GHC.IO ( IO )
144 import GHC.IO.Handle.FD ( stdout )
145 import qualified GHC.IO as New
146 import qualified GHC.IO.Exception as New
147 import GHC.Conc hiding (setUncaughtExceptionHandler,
148 getUncaughtExceptionHandler)
149 import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
150 import Foreign.C.String ( CString, withCString )
151 import GHC.IO.Handle ( hFlush )
155 import Prelude hiding (catch)
156 import Hugs.Prelude as New (ExitCode(..))
159 import qualified Control.Exception as New
160 import Control.Exception ( toException, fromException, throw, block, unblock, mask, evaluate, throwIO )
161 import System.IO.Error hiding ( catch, try )
162 import System.IO.Unsafe (unsafePerformIO)
168 import System.IO.Error (catch, ioError)
170 import DIOError -- defn of IOError type
172 -- minimum needed for nhc98 to pretend it has Exceptions
173 type Exception = IOError
174 type IOException = IOError
179 throwIO :: Exception -> IO a
181 throw :: Exception -> a
182 throw = unsafePerformIO . throwIO
184 evaluate :: a -> IO a
185 evaluate x = x `seq` return x
187 ioErrors :: Exception -> Maybe IOError
189 arithExceptions :: Exception -> Maybe ArithException
190 arithExceptions = const Nothing
191 errorCalls :: Exception -> Maybe String
192 errorCalls = const Nothing
193 dynExceptions :: Exception -> Maybe Dynamic
194 dynExceptions = const Nothing
195 assertions :: Exception -> Maybe String
196 assertions = const Nothing
197 asyncExceptions :: Exception -> Maybe AsyncException
198 asyncExceptions = const Nothing
199 userErrors :: Exception -> Maybe String
200 userErrors (UserError _ s) = Just s
201 userErrors _ = Nothing
203 block :: IO a -> IO a
205 unblock :: IO a -> IO a
208 assert :: Bool -> a -> a
210 assert False _ = throw (UserError "" "Assertion failed")
213 -----------------------------------------------------------------------------
214 -- Catching exceptions
216 -- |This is the simplest of the exception-catching functions. It
217 -- takes a single argument, runs it, and if an exception is raised
218 -- the \"handler\" is executed, with the value of the exception passed as an
219 -- argument. Otherwise, the result is returned as normal. For example:
221 -- > catch (openFile f ReadMode)
222 -- > (\e -> hPutStr stderr ("Couldn't open "++f++": " ++ show e))
224 -- For catching exceptions in pure (non-'IO') expressions, see the
225 -- function 'evaluate'.
227 -- Note that due to Haskell\'s unspecified evaluation order, an
228 -- expression may return one of several possible exceptions: consider
229 -- the expression @error \"urk\" + 1 \`div\` 0@. Does
230 -- 'catch' execute the handler passing
231 -- @ErrorCall \"urk\"@, or @ArithError DivideByZero@?
233 -- The answer is \"either\": 'catch' makes a
234 -- non-deterministic choice about which exception to catch. If you
235 -- call it again, you might get a different exception back. This is
236 -- ok, because 'catch' is an 'IO' computation.
238 -- Note that 'catch' catches all types of exceptions, and is generally
239 -- used for \"cleaning up\" before passing on the exception using
240 -- 'throwIO'. It is not good practice to discard the exception and
241 -- continue, without first checking the type of the exception (it
242 -- might be a 'ThreadKilled', for example). In this case it is usually better
243 -- to use 'catchJust' and select the kinds of exceptions to catch.
245 -- Also note that the "Prelude" also exports a function called
246 -- 'Prelude.catch' with a similar type to 'Control.OldException.catch',
247 -- except that the "Prelude" version only catches the IO and user
248 -- families of exceptions (as required by Haskell 98).
250 -- We recommend either hiding the "Prelude" version of 'Prelude.catch'
251 -- when importing "Control.OldException":
253 -- > import Prelude hiding (catch)
255 -- or importing "Control.OldException" qualified, to avoid name-clashes:
257 -- > import qualified Control.OldException as C
259 -- and then using @C.catch@
262 catch :: IO a -- ^ The computation to run
263 -> (Exception -> IO a) -- ^ Handler to invoke if an exception is raised
265 -- note: bundling the exceptions is done in the New.Exception
266 -- instance of Exception; see below.
269 -- | The function 'catchJust' is like 'catch', but it takes an extra
270 -- argument which is an /exception predicate/, a function which
271 -- selects which type of exceptions we\'re interested in. There are
272 -- some predefined exception predicates for useful subsets of
273 -- exceptions: 'ioErrors', 'arithExceptions', and so on. For example,
274 -- to catch just calls to the 'error' function, we could use
276 -- > result <- catchJust errorCalls thing_to_try handler
278 -- Any other exceptions which are not matched by the predicate
279 -- are re-raised, and may be caught by an enclosing
280 -- 'catch' or 'catchJust'.
282 :: (Exception -> Maybe b) -- ^ Predicate to select exceptions
283 -> IO a -- ^ Computation to run
284 -> (b -> IO a) -- ^ Handler
286 catchJust p a handler = catch a handler'
287 where handler' e = case p e of
291 -- | A version of 'catch' with the arguments swapped around; useful in
292 -- situations where the code for the handler is shorter. For example:
294 -- > do handle (\e -> exitWith (ExitFailure 1)) $
296 handle :: (Exception -> IO a) -> IO a -> IO a
299 -- | A version of 'catchJust' with the arguments swapped around (see
301 handleJust :: (Exception -> Maybe b) -> (b -> IO a) -> IO a -> IO a
302 handleJust p = flip (catchJust p)
304 -----------------------------------------------------------------------------
307 -- | This function maps one exception into another as proposed in the
308 -- paper \"A semantics for imprecise exceptions\".
310 -- Notice that the usage of 'unsafePerformIO' is safe here.
312 mapException :: (Exception -> Exception) -> a -> a
313 mapException f v = unsafePerformIO (catch (evaluate v)
316 -----------------------------------------------------------------------------
317 -- 'try' and variations.
319 -- | Similar to 'catch', but returns an 'Either' result which is
320 -- @('Right' a)@ if no exception was raised, or @('Left' e)@ if an
321 -- exception was raised and its value is @e@.
323 -- > try a = catch (Right `liftM` a) (return . Left)
325 -- Note: as with 'catch', it is only polite to use this variant if you intend
326 -- to re-throw the exception after performing whatever cleanup is needed.
327 -- Otherwise, 'tryJust' is generally considered to be better.
329 -- Also note that "System.IO.Error" also exports a function called
330 -- 'System.IO.Error.try' with a similar type to 'Control.OldException.try',
331 -- except that it catches only the IO and user families of exceptions
332 -- (as required by the Haskell 98 @IO@ module).
334 try :: IO a -> IO (Either Exception a)
335 try a = catch (a >>= \ v -> return (Right v)) (\e -> return (Left e))
337 -- | A variant of 'try' that takes an exception predicate to select
338 -- which exceptions are caught (c.f. 'catchJust'). If the exception
339 -- does not match the predicate, it is re-thrown.
340 tryJust :: (Exception -> Maybe b) -> IO a -> IO (Either b a)
344 Right v -> return (Right v)
345 Left e -> case p e of
347 Just b -> return (Left b)
349 -----------------------------------------------------------------------------
350 -- Dynamic exceptions
353 -- #DynamicExceptions# Because the 'Exception' datatype is not extensible, there is an
354 -- interface for throwing and catching exceptions of type 'Dynamic'
355 -- (see "Data.Dynamic") which allows exception values of any type in
356 -- the 'Typeable' class to be thrown and caught.
358 -- | Raise any value as an exception, provided it is in the
360 throwDyn :: Typeable exception => exception -> b
362 throwDyn exception = throw (UserError "" "dynamic exception")
364 throwDyn exception = throw (DynException (toDyn exception))
367 #ifdef __GLASGOW_HASKELL__
368 -- | A variant of 'throwDyn' that throws the dynamic exception to an
369 -- arbitrary thread (GHC only: c.f. 'throwTo').
370 throwDynTo :: Typeable exception => ThreadId -> exception -> IO ()
371 throwDynTo t exception = New.throwTo t (DynException (toDyn exception))
372 #endif /* __GLASGOW_HASKELL__ */
374 -- | Catch dynamic exceptions of the required type. All other
375 -- exceptions are re-thrown, including dynamic exceptions of the wrong
378 -- When using dynamic exceptions it is advisable to define a new
379 -- datatype to use for your exception type, to avoid possible clashes
380 -- with dynamic exceptions used in other libraries.
382 catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
384 catchDyn m k = m -- can't catch dyn exceptions in nhc98
386 catchDyn m k = New.catch m handler
387 where handler ex = case ex of
388 (DynException dyn) ->
389 case fromDynamic dyn of
390 Just exception -> k exception
395 -----------------------------------------------------------------------------
396 -- Exception Predicates
399 -- These pre-defined predicates may be used as the first argument to
400 -- 'catchJust', 'tryJust', or 'handleJust' to select certain common
401 -- classes of exceptions.
403 ioErrors :: Exception -> Maybe IOError
404 arithExceptions :: Exception -> Maybe New.ArithException
405 errorCalls :: Exception -> Maybe String
406 assertions :: Exception -> Maybe String
407 dynExceptions :: Exception -> Maybe Dynamic
408 asyncExceptions :: Exception -> Maybe New.AsyncException
409 userErrors :: Exception -> Maybe String
411 ioErrors (IOException e) = Just e
414 arithExceptions (ArithException e) = Just e
415 arithExceptions _ = Nothing
417 errorCalls (ErrorCall e) = Just e
418 errorCalls _ = Nothing
420 assertions (AssertionFailed e) = Just e
421 assertions _ = Nothing
423 dynExceptions (DynException e) = Just e
424 dynExceptions _ = Nothing
426 asyncExceptions (AsyncException e) = Just e
427 asyncExceptions _ = Nothing
429 userErrors (IOException e) | isUserError e = Just (ioeGetErrorString e)
430 userErrors _ = Nothing
432 -----------------------------------------------------------------------------
433 -- Some Useful Functions
435 -- | When you want to acquire a resource, do some work with it, and
436 -- then release the resource, it is a good idea to use 'bracket',
437 -- because 'bracket' will install the necessary exception handler to
438 -- release the resource in the event that an exception is raised
439 -- during the computation. If an exception is raised, then 'bracket' will
440 -- re-raise the exception (after performing the release).
442 -- A common example is opening a file:
445 -- > (openFile "filename" ReadMode)
447 -- > (\handle -> do { ... })
449 -- The arguments to 'bracket' are in this order so that we can partially apply
452 -- > withFile name mode = bracket (openFile name mode) hClose
456 :: IO a -- ^ computation to run first (\"acquire resource\")
457 -> (a -> IO b) -- ^ computation to run last (\"release resource\")
458 -> (a -> IO c) -- ^ computation to run in-between
459 -> IO c -- returns the value from the in-between computation
460 bracket before after thing =
461 mask $ \restore -> do
465 (\e -> do { _ <- after a; throw e })
470 -- | A specialised variant of 'bracket' with just a computation to run
473 finally :: IO a -- ^ computation to run first
474 -> IO b -- ^ computation to run afterward (even if an exception
476 -> IO a -- returns the value from the first computation
478 mask $ \restore -> do
481 (\e -> do { _ <- sequel; throw e })
485 -- | A variant of 'bracket' where the return value from the first computation
487 bracket_ :: IO a -> IO b -> IO c -> IO c
488 bracket_ before after thing = bracket before (const after) (const thing)
490 -- | Like bracket, but only performs the final action if there was an
491 -- exception raised by the in-between computation.
493 :: IO a -- ^ computation to run first (\"acquire resource\")
494 -> (a -> IO b) -- ^ computation to run last (\"release resource\")
495 -> (a -> IO c) -- ^ computation to run in-between
496 -> IO c -- returns the value from the in-between computation
497 bracketOnError before after thing =
498 mask $ \restore -> do
502 (\e -> do { _ <- after a; throw e })
504 -- -----------------------------------------------------------------------------
505 -- Asynchronous exceptions
509 #AsynchronousExceptions# Asynchronous exceptions are so-called because they arise due to
510 external influences, and can be raised at any point during execution.
511 'StackOverflow' and 'HeapOverflow' are two examples of
512 system-generated asynchronous exceptions.
514 The primary source of asynchronous exceptions, however, is
517 > throwTo :: ThreadId -> Exception -> IO ()
519 'throwTo' (also 'throwDynTo' and 'Control.Concurrent.killThread') allows one
520 running thread to raise an arbitrary exception in another thread. The
521 exception is therefore asynchronous with respect to the target thread,
522 which could be doing anything at the time it receives the exception.
523 Great care should be taken with asynchronous exceptions; it is all too
524 easy to introduce race conditions by the over zealous use of
529 There\'s an implied 'mask_' around every exception handler in a call
530 to one of the 'catch' family of functions. This is because that is
531 what you want most of the time - it eliminates a common race condition
532 in starting an exception handler, because there may be no exception
533 handler on the stack to handle another exception if one arrives
534 immediately. If asynchronous exceptions are blocked on entering the
535 handler, though, we have time to install a new exception handler
536 before being interrupted. If this weren\'t the default, one would have
537 to write something like
540 > catch (restore (...))
543 If you need to unblock asynchronous exceptions again in the exception
544 handler, just use 'unblock' as normal.
546 Note that 'try' and friends /do not/ have a similar default, because
547 there is no exception handler in this case. If you want to use 'try'
548 in an asynchronous-exception-safe way, you will need to use
554 Some operations are /interruptible/, which means that they can receive
555 asynchronous exceptions even in the scope of a 'mask'. Any function
556 which may itself block is defined as interruptible; this includes
557 'Control.Concurrent.MVar.takeMVar'
558 (but not 'Control.Concurrent.MVar.tryTakeMVar'),
559 and most operations which perform
560 some I\/O with the outside world. The reason for having
561 interruptible operations is so that we can write things like
563 > mask $ \restore -> do
565 > catch (restore (...))
568 if the 'Control.Concurrent.MVar.takeMVar' was not interruptible,
570 combination could lead to deadlock, because the thread itself would be
571 blocked in a state where it can\'t receive any asynchronous exceptions.
572 With 'Control.Concurrent.MVar.takeMVar' interruptible, however, we can be
573 safe in the knowledge that the thread can receive exceptions right up
574 until the point when the 'Control.Concurrent.MVar.takeMVar' succeeds.
575 Similar arguments apply for other interruptible operations like
576 'System.IO.openFile'.
579 #if !(__GLASGOW_HASKELL__ || __NHC__)
580 assert :: Bool -> a -> a
582 assert False _ = throw (AssertionFailed "")
586 #ifdef __GLASGOW_HASKELL__
587 {-# NOINLINE uncaughtExceptionHandler #-}
588 uncaughtExceptionHandler :: IORef (Exception -> IO ())
589 uncaughtExceptionHandler = unsafePerformIO (newIORef defaultHandler)
591 defaultHandler :: Exception -> IO ()
592 defaultHandler ex = do
593 (hFlush stdout) `New.catchAny` (\ _ -> return ())
595 Deadlock -> "no threads to run: infinite loop or deadlock?"
597 other -> showsPrec 0 other ""
598 withCString "%s" $ \cfmt ->
599 withCString msg $ \cmsg ->
602 -- don't use errorBelch() directly, because we cannot call varargs functions
604 foreign import ccall unsafe "HsBase.h errorBelch2"
605 errorBelch :: CString -> CString -> IO ()
607 setUncaughtExceptionHandler :: (Exception -> IO ()) -> IO ()
608 setUncaughtExceptionHandler = writeIORef uncaughtExceptionHandler
610 getUncaughtExceptionHandler :: IO (Exception -> IO ())
611 getUncaughtExceptionHandler = readIORef uncaughtExceptionHandler
614 -- ------------------------------------------------------------------------
615 -- Exception datatype and operations
617 -- |The type of exceptions. Every kind of system-generated exception
618 -- has a constructor in the 'Exception' type, and values of other
619 -- types may be injected into 'Exception' by coercing them to
620 -- 'Data.Dynamic.Dynamic' (see the section on Dynamic Exceptions:
621 -- "Control.OldException\#DynamicExceptions").
623 = ArithException New.ArithException
624 -- ^Exceptions raised by arithmetic
625 -- operations. (NOTE: GHC currently does not throw
626 -- 'ArithException's except for 'DivideByZero').
627 | ArrayException New.ArrayException
628 -- ^Exceptions raised by array-related
629 -- operations. (NOTE: GHC currently does not throw
630 -- 'ArrayException's).
631 | AssertionFailed String
632 -- ^This exception is thrown by the
633 -- 'assert' operation when the condition
634 -- fails. The 'String' argument contains the
635 -- location of the assertion in the source program.
636 | AsyncException New.AsyncException
637 -- ^Asynchronous exceptions (see section on Asynchronous Exceptions: "Control.OldException\#AsynchronousExceptions").
639 -- ^The current thread was executing a call to
640 -- 'Control.Concurrent.MVar.takeMVar' that could never return,
641 -- because there are no other references to this 'MVar'.
642 | BlockedIndefinitely
643 -- ^The current thread was waiting to retry an atomic memory transaction
644 -- that could never become possible to complete because there are no other
645 -- threads referring to any of the TVars involved.
647 -- ^The runtime detected an attempt to nest one STM transaction
648 -- inside another one, presumably due to the use of
649 -- 'unsafePeformIO' with 'atomically'.
651 -- ^There are no runnable threads, so the program is
652 -- deadlocked. The 'Deadlock' exception is
653 -- raised in the main thread only (see also: "Control.Concurrent").
654 | DynException Dynamic
655 -- ^Dynamically typed exceptions (see section on Dynamic Exceptions: "Control.OldException\#DynamicExceptions").
657 -- ^The 'ErrorCall' exception is thrown by 'error'. The 'String'
658 -- argument of 'ErrorCall' is the string passed to 'error' when it was
660 | ExitException New.ExitCode
661 -- ^The 'ExitException' exception is thrown by 'System.Exit.exitWith' (and
662 -- 'System.Exit.exitFailure'). The 'ExitCode' argument is the value passed
663 -- to 'System.Exit.exitWith'. An unhandled 'ExitException' exception in the
664 -- main thread will cause the program to be terminated with the given
666 | IOException New.IOException
667 -- ^These are the standard IO exceptions generated by
668 -- Haskell\'s @IO@ operations. See also "System.IO.Error".
669 | NoMethodError String
670 -- ^An attempt was made to invoke a class method which has
671 -- no definition in this instance, and there was no default
672 -- definition given in the class declaration. GHC issues a
673 -- warning when you compile an instance which has missing
676 -- ^The current thread is stuck in an infinite loop. This
677 -- exception may or may not be thrown when the program is
679 | PatternMatchFail String
680 -- ^A pattern matching failure. The 'String' argument should contain a
681 -- descriptive message including the function name, source file
684 -- ^An attempt was made to evaluate a field of a record
685 -- for which no value was given at construction time. The
686 -- 'String' argument gives the location of the
687 -- record construction in the source program.
689 -- ^A field selection was attempted on a constructor that
690 -- doesn\'t have the requested field. This can happen with
691 -- multi-constructor records when one or more fields are
692 -- missing from some of the constructors. The
693 -- 'String' argument gives the location of the
694 -- record selection in the source program.
696 -- ^An attempt was made to update a field in a record,
697 -- where the record doesn\'t have the requested field. This can
698 -- only occur with multi-constructor records, when one or more
699 -- fields are missing from some of the constructors. The
700 -- 'String' argument gives the location of the
701 -- record update in the source program.
702 INSTANCE_TYPEABLE0(Exception,exceptionTc,"Exception")
704 -- helper type for simplifying the type casting logic below
705 data Caster = forall e . New.Exception e => Caster (e -> Exception)
707 instance New.Exception Exception where
708 -- We need to collect all the sorts of exceptions that used to be
709 -- bundled up into the Exception type, and rebundle them for
711 fromException exc0 = foldr tryCast Nothing casters where
712 tryCast (Caster f) e = case fromException exc0 of
713 Just exc -> Just (f exc)
716 [Caster (\exc -> ArithException exc),
717 Caster (\exc -> ArrayException exc),
718 Caster (\(New.AssertionFailed err) -> AssertionFailed err),
719 Caster (\exc -> AsyncException exc),
720 Caster (\New.BlockedIndefinitelyOnMVar -> BlockedOnDeadMVar),
721 Caster (\New.BlockedIndefinitelyOnSTM -> BlockedIndefinitely),
722 Caster (\New.NestedAtomically -> NestedAtomically),
723 Caster (\New.Deadlock -> Deadlock),
724 Caster (\exc -> DynException exc),
725 Caster (\(New.ErrorCall err) -> ErrorCall err),
726 Caster (\exc -> ExitException exc),
727 Caster (\exc -> IOException exc),
728 Caster (\(New.NoMethodError err) -> NoMethodError err),
729 Caster (\New.NonTermination -> NonTermination),
730 Caster (\(New.PatternMatchFail err) -> PatternMatchFail err),
731 Caster (\(New.RecConError err) -> RecConError err),
732 Caster (\(New.RecSelError err) -> RecSelError err),
733 Caster (\(New.RecUpdError err) -> RecUpdError err),
734 -- Anything else gets taken as a Dynamic exception. It's
735 -- important that we put all exceptions into the old Exception
736 -- type somehow, or throwing a new exception wouldn't cause
737 -- the cleanup code for bracket, finally etc to happen.
738 Caster (\exc -> DynException (toDyn (exc :: New.SomeException)))]
740 -- Unbundle exceptions.
741 toException (ArithException exc) = toException exc
742 toException (ArrayException exc) = toException exc
743 toException (AssertionFailed err) = toException (New.AssertionFailed err)
744 toException (AsyncException exc) = toException exc
745 toException BlockedOnDeadMVar = toException New.BlockedIndefinitelyOnMVar
746 toException BlockedIndefinitely = toException New.BlockedIndefinitelyOnSTM
747 toException NestedAtomically = toException New.NestedAtomically
748 toException Deadlock = toException New.Deadlock
749 -- If a dynamic exception is a SomeException then resurrect it, so
750 -- that bracket, catch+throw etc rethrow the same exception even
751 -- when the exception is in the new style.
752 -- If it's not a SomeException, then just throw the Dynamic.
753 toException (DynException exc) = case fromDynamic exc of
755 Nothing -> toException exc
756 toException (ErrorCall err) = toException (New.ErrorCall err)
757 toException (ExitException exc) = toException exc
758 toException (IOException exc) = toException exc
759 toException (NoMethodError err) = toException (New.NoMethodError err)
760 toException NonTermination = toException New.NonTermination
761 toException (PatternMatchFail err) = toException (New.PatternMatchFail err)
762 toException (RecConError err) = toException (New.RecConError err)
763 toException (RecSelError err) = toException (New.RecSelError err)
764 toException (RecUpdError err) = toException (New.RecUpdError err)
766 instance Show Exception where
767 showsPrec _ (IOException err) = shows err
768 showsPrec _ (ArithException err) = shows err
769 showsPrec _ (ArrayException err) = shows err
770 showsPrec _ (ErrorCall err) = showString err
771 showsPrec _ (ExitException err) = showString "exit: " . shows err
772 showsPrec _ (NoMethodError err) = showString err
773 showsPrec _ (PatternMatchFail err) = showString err
774 showsPrec _ (RecSelError err) = showString err
775 showsPrec _ (RecConError err) = showString err
776 showsPrec _ (RecUpdError err) = showString err
777 showsPrec _ (AssertionFailed err) = showString err
778 showsPrec _ (DynException err) = showString "exception :: " . showsTypeRep (dynTypeRep err)
779 showsPrec _ (AsyncException e) = shows e
780 showsPrec p BlockedOnDeadMVar = showsPrec p New.BlockedIndefinitelyOnMVar
781 showsPrec p BlockedIndefinitely = showsPrec p New.BlockedIndefinitelyOnSTM
782 showsPrec p NestedAtomically = showsPrec p New.NestedAtomically
783 showsPrec p NonTermination = showsPrec p New.NonTermination
784 showsPrec p Deadlock = showsPrec p New.Deadlock
786 instance Eq Exception where
787 IOException e1 == IOException e2 = e1 == e2
788 ArithException e1 == ArithException e2 = e1 == e2
789 ArrayException e1 == ArrayException e2 = e1 == e2
790 ErrorCall e1 == ErrorCall e2 = e1 == e2
791 ExitException e1 == ExitException e2 = e1 == e2
792 NoMethodError e1 == NoMethodError e2 = e1 == e2
793 PatternMatchFail e1 == PatternMatchFail e2 = e1 == e2
794 RecSelError e1 == RecSelError e2 = e1 == e2
795 RecConError e1 == RecConError e2 = e1 == e2
796 RecUpdError e1 == RecUpdError e2 = e1 == e2
797 AssertionFailed e1 == AssertionFailed e2 = e1 == e2
798 DynException _ == DynException _ = False -- incomparable
799 AsyncException e1 == AsyncException e2 = e1 == e2
800 BlockedOnDeadMVar == BlockedOnDeadMVar = True
801 NonTermination == NonTermination = True
802 NestedAtomically == NestedAtomically = True
803 Deadlock == Deadlock = True