6442d6789daf23eb7a4c6ac041aee118a3be655f
[packages/base.git] / Control / OldException.hs
1 {-# LANGUAGE CPP
2 , NoImplicitPrelude
3 , ForeignFunctionInterface
4 , ExistentialQuantification
5 #-}
6 #ifdef __GLASGOW_HASKELL__
7 {-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}
8 #endif
9
10 #include "Typeable.h"
11
12 -----------------------------------------------------------------------------
13 -- |
14 -- Module : Control.OldException
15 -- Copyright : (c) The University of Glasgow 2001
16 -- License : BSD-style (see the file libraries/base/LICENSE)
17 --
18 -- Maintainer : libraries@haskell.org
19 -- Stability : experimental
20 -- Portability : non-portable (extended exceptions)
21 --
22 -- This module provides support for raising and catching both built-in
23 -- and user-defined exceptions.
24 --
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:
29 --
30 -- * /A semantics for imprecise exceptions/, by Simon Peyton Jones,
31 -- Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson,
32 -- in /PLDI'99/.
33 --
34 -- * /Asynchronous exceptions in Haskell/, by Simon Marlow, Simon Peyton
35 -- Jones, Andy Moran and John Reppy, in /PLDI'01/.
36 --
37 -----------------------------------------------------------------------------
38
39 module Control.OldException {-# DEPRECATED "Future versions of base will not support the old exceptions style. Please switch to extensible exceptions." #-} (
40
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
47
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
55 #endif
56
57 -- * Catching Exceptions
58
59 -- |There are several functions for catching and examining
60 -- exceptions; all of them may only be used from within the
61 -- 'IO' monad.
62
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
66
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
70
71 -- ** The @try@ functions
72 try, -- :: IO a -> IO (Either Exception a)
73 tryJust, -- :: (Exception -> Maybe b) -> a -> IO (Either b a)
74
75 -- ** The @evaluate@ function
76 evaluate, -- :: a -> IO a
77
78 -- ** The @mapException@ function
79 mapException, -- :: (Exception -> Exception) -> a -> a
80
81 -- ** Exception predicates
82
83 -- $preds
84
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
92
93 -- * Dynamic exceptions
94
95 -- $dynamic
96 throwDyn, -- :: Typeable ex => ex -> b
97 #ifdef __GLASGOW_HASKELL__
98 throwDynTo, -- :: Typeable ex => ThreadId -> ex -> b
99 #endif
100 catchDyn, -- :: Typeable ex => IO a -> (ex -> IO a) -> IO a
101
102 -- * Asynchronous Exceptions
103
104 -- $async
105
106 -- ** Asynchronous exception control
107
108 -- |The following two functions allow a thread to control delivery of
109 -- asynchronous exceptions during a critical region.
110
111 block, -- :: IO a -> IO a
112 unblock, -- :: IO a -> IO a
113
114 -- *** Applying @block@ to an exception handler
115
116 -- $block_handler
117
118 -- *** Interruptible operations
119
120 -- $interruptible
121
122 -- * Assertions
123
124 assert, -- :: Bool -> a -> a
125
126 -- * Utilities
127
128 bracket, -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
129 bracket_, -- :: IO a -> IO b -> IO c -> IO ()
130 bracketOnError,
131
132 finally, -- :: IO a -> IO b -> IO a
133
134 #ifdef __GLASGOW_HASKELL__
135 setUncaughtExceptionHandler, -- :: (Exception -> IO ()) -> IO ()
136 getUncaughtExceptionHandler -- :: IO (Exception -> IO ())
137 #endif
138 ) where
139
140 #ifdef __GLASGOW_HASKELL__
141 import GHC.Base
142 import GHC.Show
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 )
152 #endif
153
154 #ifdef __HUGS__
155 import Prelude hiding (catch)
156 import Hugs.Prelude as New (ExitCode(..))
157 #endif
158
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)
163 import Data.Dynamic
164 import Data.Either
165 import Data.Maybe
166
167 #ifdef __NHC__
168 import System.IO.Error (catch, ioError)
169 import IO (bracket)
170 import DIOError -- defn of IOError type
171
172 -- minimum needed for nhc98 to pretend it has Exceptions
173 type Exception = IOError
174 type IOException = IOError
175 data ArithException
176 data ArrayException
177 data AsyncException
178
179 throwIO :: Exception -> IO a
180 throwIO = ioError
181 throw :: Exception -> a
182 throw = unsafePerformIO . throwIO
183
184 evaluate :: a -> IO a
185 evaluate x = x `seq` return x
186
187 ioErrors :: Exception -> Maybe IOError
188 ioErrors e = Just e
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
202
203 block :: IO a -> IO a
204 block = id
205 unblock :: IO a -> IO a
206 unblock = id
207
208 assert :: Bool -> a -> a
209 assert True x = x
210 assert False _ = throw (UserError "" "Assertion failed")
211 #endif
212
213 -----------------------------------------------------------------------------
214 -- Catching exceptions
215
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:
220 --
221 -- > catch (openFile f ReadMode)
222 -- > (\e -> hPutStr stderr ("Couldn't open "++f++": " ++ show e))
223 --
224 -- For catching exceptions in pure (non-'IO') expressions, see the
225 -- function 'evaluate'.
226 --
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@?
232 --
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.
237 --
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.
244 --
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).
249 --
250 -- We recommend either hiding the "Prelude" version of 'Prelude.catch'
251 -- when importing "Control.OldException":
252 --
253 -- > import Prelude hiding (catch)
254 --
255 -- or importing "Control.OldException" qualified, to avoid name-clashes:
256 --
257 -- > import qualified Control.OldException as C
258 --
259 -- and then using @C.catch@
260 --
261
262 catch :: IO a -- ^ The computation to run
263 -> (Exception -> IO a) -- ^ Handler to invoke if an exception is raised
264 -> IO a
265 -- note: bundling the exceptions is done in the New.Exception
266 -- instance of Exception; see below.
267 catch = New.catch
268
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
275 --
276 -- > result <- catchJust errorCalls thing_to_try handler
277 --
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'.
281 catchJust
282 :: (Exception -> Maybe b) -- ^ Predicate to select exceptions
283 -> IO a -- ^ Computation to run
284 -> (b -> IO a) -- ^ Handler
285 -> IO a
286 catchJust p a handler = catch a handler'
287 where handler' e = case p e of
288 Nothing -> throw e
289 Just b -> handler b
290
291 -- | A version of 'catch' with the arguments swapped around; useful in
292 -- situations where the code for the handler is shorter. For example:
293 --
294 -- > do handle (\e -> exitWith (ExitFailure 1)) $
295 -- > ...
296 handle :: (Exception -> IO a) -> IO a -> IO a
297 handle = flip catch
298
299 -- | A version of 'catchJust' with the arguments swapped around (see
300 -- 'handle').
301 handleJust :: (Exception -> Maybe b) -> (b -> IO a) -> IO a -> IO a
302 handleJust p = flip (catchJust p)
303
304 -----------------------------------------------------------------------------
305 -- 'mapException'
306
307 -- | This function maps one exception into another as proposed in the
308 -- paper \"A semantics for imprecise exceptions\".
309
310 -- Notice that the usage of 'unsafePerformIO' is safe here.
311
312 mapException :: (Exception -> Exception) -> a -> a
313 mapException f v = unsafePerformIO (catch (evaluate v)
314 (\x -> throw (f x)))
315
316 -----------------------------------------------------------------------------
317 -- 'try' and variations.
318
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@.
322 --
323 -- > try a = catch (Right `liftM` a) (return . Left)
324 --
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.
328 --
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).
333
334 try :: IO a -> IO (Either Exception a)
335 try a = catch (a >>= \ v -> return (Right v)) (\e -> return (Left e))
336
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)
341 tryJust p a = do
342 r <- try a
343 case r of
344 Right v -> return (Right v)
345 Left e -> case p e of
346 Nothing -> throw e
347 Just b -> return (Left b)
348
349 -----------------------------------------------------------------------------
350 -- Dynamic exceptions
351
352 -- $dynamic
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.
357
358 -- | Raise any value as an exception, provided it is in the
359 -- 'Typeable' class.
360 throwDyn :: Typeable exception => exception -> b
361 #ifdef __NHC__
362 throwDyn exception = throw (UserError "" "dynamic exception")
363 #else
364 throwDyn exception = throw (DynException (toDyn exception))
365 #endif
366
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__ */
373
374 -- | Catch dynamic exceptions of the required type. All other
375 -- exceptions are re-thrown, including dynamic exceptions of the wrong
376 -- type.
377 --
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.
381 --
382 catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
383 #ifdef __NHC__
384 catchDyn m k = m -- can't catch dyn exceptions in nhc98
385 #else
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
391 Nothing -> throw ex
392 _ -> throw ex
393 #endif
394
395 -----------------------------------------------------------------------------
396 -- Exception Predicates
397
398 -- $preds
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.
402 #ifndef __NHC__
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
410
411 ioErrors (IOException e) = Just e
412 ioErrors _ = Nothing
413
414 arithExceptions (ArithException e) = Just e
415 arithExceptions _ = Nothing
416
417 errorCalls (ErrorCall e) = Just e
418 errorCalls _ = Nothing
419
420 assertions (AssertionFailed e) = Just e
421 assertions _ = Nothing
422
423 dynExceptions (DynException e) = Just e
424 dynExceptions _ = Nothing
425
426 asyncExceptions (AsyncException e) = Just e
427 asyncExceptions _ = Nothing
428
429 userErrors (IOException e) | isUserError e = Just (ioeGetErrorString e)
430 userErrors _ = Nothing
431 #endif
432 -----------------------------------------------------------------------------
433 -- Some Useful Functions
434
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).
441 --
442 -- A common example is opening a file:
443 --
444 -- > bracket
445 -- > (openFile "filename" ReadMode)
446 -- > (hClose)
447 -- > (\handle -> do { ... })
448 --
449 -- The arguments to 'bracket' are in this order so that we can partially apply
450 -- it, e.g.:
451 --
452 -- > withFile name mode = bracket (openFile name mode) hClose
453 --
454 #ifndef __NHC__
455 bracket
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
462 a <- before
463 r <- catch
464 (restore (thing a))
465 (\e -> do { _ <- after a; throw e })
466 _ <- after a
467 return r
468 #endif
469
470 -- | A specialised variant of 'bracket' with just a computation to run
471 -- afterward.
472 --
473 finally :: IO a -- ^ computation to run first
474 -> IO b -- ^ computation to run afterward (even if an exception
475 -- was raised)
476 -> IO a -- returns the value from the first computation
477 a `finally` sequel =
478 mask $ \restore -> do
479 r <- catch
480 (restore a)
481 (\e -> do { _ <- sequel; throw e })
482 _ <- sequel
483 return r
484
485 -- | A variant of 'bracket' where the return value from the first computation
486 -- is not required.
487 bracket_ :: IO a -> IO b -> IO c -> IO c
488 bracket_ before after thing = bracket before (const after) (const thing)
489
490 -- | Like bracket, but only performs the final action if there was an
491 -- exception raised by the in-between computation.
492 bracketOnError
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
499 a <- before
500 catch
501 (restore (thing a))
502 (\e -> do { _ <- after a; throw e })
503
504 -- -----------------------------------------------------------------------------
505 -- Asynchronous exceptions
506
507 {- $async
508
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.
513
514 The primary source of asynchronous exceptions, however, is
515 'throwTo':
516
517 > throwTo :: ThreadId -> Exception -> IO ()
518
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
525 'throwTo'.
526 -}
527
528 {- $block_handler
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
538
539 > mask $ \restore ->
540 > catch (restore (...))
541 > (\e -> handler)
542
543 If you need to unblock asynchronous exceptions again in the exception
544 handler, just use 'unblock' as normal.
545
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
549 'mask'.
550 -}
551
552 {- $interruptible
553
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
562
563 > mask $ \restore -> do
564 > a <- takeMVar m
565 > catch (restore (...))
566 > (\e -> ...)
567
568 if the 'Control.Concurrent.MVar.takeMVar' was not interruptible,
569 then this particular
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'.
577 -}
578
579 #if !(__GLASGOW_HASKELL__ || __NHC__)
580 assert :: Bool -> a -> a
581 assert True x = x
582 assert False _ = throw (AssertionFailed "")
583 #endif
584
585
586 #ifdef __GLASGOW_HASKELL__
587 {-# NOINLINE uncaughtExceptionHandler #-}
588 uncaughtExceptionHandler :: IORef (Exception -> IO ())
589 uncaughtExceptionHandler = unsafePerformIO (newIORef defaultHandler)
590 where
591 defaultHandler :: Exception -> IO ()
592 defaultHandler ex = do
593 (hFlush stdout) `New.catchAny` (\ _ -> return ())
594 let msg = case ex of
595 Deadlock -> "no threads to run: infinite loop or deadlock?"
596 ErrorCall s -> s
597 other -> showsPrec 0 other ""
598 withCString "%s" $ \cfmt ->
599 withCString msg $ \cmsg ->
600 errorBelch cfmt cmsg
601
602 -- don't use errorBelch() directly, because we cannot call varargs functions
603 -- using the FFI.
604 foreign import ccall unsafe "HsBase.h errorBelch2"
605 errorBelch :: CString -> CString -> IO ()
606
607 setUncaughtExceptionHandler :: (Exception -> IO ()) -> IO ()
608 setUncaughtExceptionHandler = writeIORef uncaughtExceptionHandler
609
610 getUncaughtExceptionHandler :: IO (Exception -> IO ())
611 getUncaughtExceptionHandler = readIORef uncaughtExceptionHandler
612 #endif
613
614 -- ------------------------------------------------------------------------
615 -- Exception datatype and operations
616
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").
622 data Exception
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").
638 | BlockedOnDeadMVar
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.
646 | NestedAtomically
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'.
650 | Deadlock
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").
656 | ErrorCall String
657 -- ^The 'ErrorCall' exception is thrown by 'error'. The 'String'
658 -- argument of 'ErrorCall' is the string passed to 'error' when it was
659 -- called.
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
665 -- exit code.
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
674 -- methods.
675 | NonTermination
676 -- ^The current thread is stuck in an infinite loop. This
677 -- exception may or may not be thrown when the program is
678 -- non-terminating.
679 | PatternMatchFail String
680 -- ^A pattern matching failure. The 'String' argument should contain a
681 -- descriptive message including the function name, source file
682 -- and line number.
683 | RecConError String
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.
688 | RecSelError String
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.
695 | RecUpdError String
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")
703
704 -- helper type for simplifying the type casting logic below
705 data Caster = forall e . New.Exception e => Caster (e -> Exception)
706
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
710 -- legacy handlers.
711 fromException exc0 = foldr tryCast Nothing casters where
712 tryCast (Caster f) e = case fromException exc0 of
713 Just exc -> Just (f exc)
714 _ -> e
715 casters =
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)))]
739
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
754 Just exc' -> exc'
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)
765
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
785
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
804 _ == _ = False
805