split most of Control.Exception into new Control.Exception.Base
[ghc-base.git] / Control / Exception / Base.hs
1 {-# OPTIONS_GHC -XNoImplicitPrelude #-}
2
3 #include "Typeable.h"
4
5 -----------------------------------------------------------------------------
6 -- |
7 -- Module      :  Control.Exception.Base
8 -- Copyright   :  (c) The University of Glasgow 2001
9 -- License     :  BSD-style (see the file libraries/base/LICENSE)
10 -- 
11 -- Maintainer  :  libraries@haskell.org
12 -- Stability   :  experimental
13 -- Portability :  non-portable (extended exceptions)
14 --
15 -- Extensible exceptions, except for multiple handlers.
16 --
17 -----------------------------------------------------------------------------
18
19 module Control.Exception.Base (
20
21         -- * The Exception type
22 #ifdef __HUGS__
23         SomeException,
24 #else
25         SomeException(..),
26 #endif
27         Exception(..),
28         IOException,
29         ArithException(..),
30         ArrayException(..),
31         AssertionFailed(..),
32         AsyncException(..),
33
34 #if __GLASGOW_HASKELL__ || __HUGS__
35         NonTermination(..),
36         NestedAtomically(..),
37 #endif
38
39         BlockedOnDeadMVar(..),
40         BlockedIndefinitely(..),
41         Deadlock(..),
42         NoMethodError(..),
43         PatternMatchFail(..),
44         RecConError(..),
45         RecSelError(..),
46         RecUpdError(..),
47         ErrorCall(..),
48
49         -- * Throwing exceptions
50         throwIO,
51         throw,
52         ioError,
53 #ifdef __GLASGOW_HASKELL__
54         throwTo,
55 #endif
56
57         -- * Catching Exceptions
58
59         -- ** The @catch@ functions
60         catch,
61         catchJust,
62
63         -- ** The @handle@ functions
64         handle,
65         handleJust,
66
67         -- ** The @try@ functions
68         try,
69         tryJust,
70         onException,
71
72         -- ** The @evaluate@ function
73         evaluate,
74
75         -- ** The @mapException@ function
76         mapException,
77
78         -- * Asynchronous Exceptions
79
80         -- ** Asynchronous exception control
81
82         block,
83         unblock,
84         blocked,
85
86         -- * Assertions
87
88         assert,
89
90         -- * Utilities
91
92         bracket,
93         bracket_,
94         bracketOnError,
95
96         finally,
97
98 #ifdef __GLASGOW_HASKELL__
99         -- * Calls for GHC runtime
100         recSelError, recConError, irrefutPatError, runtimeError,
101         nonExhaustiveGuardsError, patError, noMethodBindingError,
102         nonTermination, nestedAtomically,
103 #endif
104   ) where
105
106 #ifdef __GLASGOW_HASKELL__
107 import GHC.Base
108 import GHC.IOBase
109 import GHC.List
110 import GHC.Show
111 import GHC.IOBase
112 import GHC.Exception hiding ( Exception )
113 import GHC.Conc
114 #endif
115
116 #ifdef __HUGS__
117 import Prelude hiding (catch)
118 import Hugs.Prelude (ExitCode(..))
119 import Hugs.IOExts (unsafePerformIO)
120 import Hugs.Exception (SomeException(DynamicException, IOException,
121                                      ArithException, ArrayException, ExitException),
122                        evaluate, IOException, ArithException, ArrayException)
123 import qualified Hugs.Exception
124 #endif
125
126 import Data.Dynamic
127 import Data.Either
128 import Data.Maybe
129
130 #ifdef __NHC__
131 import qualified System.IO.Error as H'98 (catch)
132 import System.IO.Error (ioError)
133 import IO              (bracket)
134 import DIOError         -- defn of IOError type
135 import System          (ExitCode())
136 import System.IO.Unsafe (unsafePerformIO)
137 import Unsafe.Coerce    (unsafeCoerce)
138
139 -- minimum needed for nhc98 to pretend it has Exceptions
140
141 {-
142 data Exception   = IOException    IOException
143                  | ArithException ArithException
144                  | ArrayException ArrayException
145                  | AsyncException AsyncException
146                  | ExitException  ExitCode
147                  deriving Show
148 -}
149 class ({-Typeable e,-} Show e) => Exception e where
150     toException   :: e -> SomeException
151     fromException :: SomeException -> Maybe e
152
153 data SomeException = forall e . Exception e => SomeException e
154
155 INSTANCE_TYPEABLE0(SomeException,someExceptionTc,"SomeException")
156
157 instance Show SomeException where
158     showsPrec p (SomeException e) = showsPrec p e
159 instance Exception SomeException where
160     toException se = se
161     fromException = Just
162
163 type IOException = IOError
164 instance Exception IOError where
165     toException                     = SomeException
166     fromException (SomeException e) = Just (unsafeCoerce e)
167
168 instance Exception ExitCode where
169     toException                     = SomeException
170     fromException (SomeException e) = Just (unsafeCoerce e)
171
172 data ArithException
173 data ArrayException
174 data AsyncException
175 data AssertionFailed
176 data PatternMatchFail
177 data NoMethodError
178 data Deadlock
179 data BlockedOnDeadMVar
180 data BlockedIndefinitely
181 data ErrorCall
182 data RecConError
183 data RecSelError
184 data RecUpdError
185 instance Show ArithException
186 instance Show ArrayException
187 instance Show AsyncException
188 instance Show AssertionFailed
189 instance Show PatternMatchFail
190 instance Show NoMethodError
191 instance Show Deadlock
192 instance Show BlockedOnDeadMVar
193 instance Show BlockedIndefinitely
194 instance Show ErrorCall
195 instance Show RecConError
196 instance Show RecSelError
197 instance Show RecUpdError
198
199 catch   :: Exception e
200         => IO a         -- ^ The computation to run
201         -> (e -> IO a)  -- ^ Handler to invoke if an exception is raised
202         -> IO a
203 catch io h = H'98.catch  io  (h . fromJust . fromException . toException)
204
205 throwIO  :: Exception e => e -> IO a
206 throwIO   = ioError . fromJust . fromException . toException
207
208 throw    :: Exception e => e -> a
209 throw     = unsafePerformIO . throwIO
210
211 evaluate :: a -> IO a
212 evaluate x = x `seq` return x
213
214 assert :: Bool -> a -> a
215 assert True  x = x
216 assert False _ = throw (toException (UserError "" "Assertion failed"))
217
218 #endif
219
220 #ifdef __HUGS__
221 class (Typeable e, Show e) => Exception e where
222     toException   :: e -> SomeException
223     fromException :: SomeException -> Maybe e
224
225     toException e = DynamicException (toDyn e) (flip showsPrec e)
226     fromException (DynamicException dyn _) = fromDynamic dyn
227     fromException _ = Nothing
228
229 INSTANCE_TYPEABLE0(SomeException,someExceptionTc,"SomeException")
230 INSTANCE_TYPEABLE0(IOException,iOExceptionTc,"IOException")
231 INSTANCE_TYPEABLE0(ArithException,arithExceptionTc,"ArithException")
232 INSTANCE_TYPEABLE0(ArrayException,arrayExceptionTc,"ArrayException")
233 INSTANCE_TYPEABLE0(ExitCode,exitCodeTc,"ExitCode")
234 INSTANCE_TYPEABLE0(ErrorCall,errorCallTc,"ErrorCall")
235 INSTANCE_TYPEABLE0(AssertionFailed,assertionFailedTc,"AssertionFailed")
236 INSTANCE_TYPEABLE0(AsyncException,asyncExceptionTc,"AsyncException")
237 INSTANCE_TYPEABLE0(BlockedOnDeadMVar,blockedOnDeadMVarTc,"BlockedOnDeadMVar")
238 INSTANCE_TYPEABLE0(BlockedIndefinitely,blockedIndefinitelyTc,"BlockedIndefinitely")
239 INSTANCE_TYPEABLE0(Deadlock,deadlockTc,"Deadlock")
240
241 instance Exception SomeException where
242     toException se = se
243     fromException = Just
244
245 instance Exception IOException where
246     toException = IOException
247     fromException (IOException e) = Just e
248     fromException _ = Nothing
249
250 instance Exception ArrayException where
251     toException = ArrayException
252     fromException (ArrayException e) = Just e
253     fromException _ = Nothing
254
255 instance Exception ArithException where
256     toException = ArithException
257     fromException (ArithException e) = Just e
258     fromException _ = Nothing
259
260 instance Exception ExitCode where
261     toException = ExitException
262     fromException (ExitException e) = Just e
263     fromException _ = Nothing
264
265 data ErrorCall = ErrorCall String
266
267 instance Show ErrorCall where
268     showsPrec _ (ErrorCall err) = showString err
269
270 instance Exception ErrorCall where
271     toException (ErrorCall s) = Hugs.Exception.ErrorCall s
272     fromException (Hugs.Exception.ErrorCall s) = Just (ErrorCall s)
273     fromException _ = Nothing
274
275 data BlockedOnDeadMVar = BlockedOnDeadMVar
276 data BlockedIndefinitely = BlockedIndefinitely
277 data Deadlock = Deadlock
278 data AssertionFailed = AssertionFailed String
279 data AsyncException
280   = StackOverflow
281   | HeapOverflow
282   | ThreadKilled
283   | UserInterrupt
284   deriving (Eq, Ord)
285
286 instance Show BlockedOnDeadMVar where
287     showsPrec _ BlockedOnDeadMVar = showString "thread blocked indefinitely"
288
289 instance Show BlockedIndefinitely where
290     showsPrec _ BlockedIndefinitely = showString "thread blocked indefinitely"
291
292 instance Show Deadlock where
293     showsPrec _ Deadlock = showString "<<deadlock>>"
294
295 instance Show AssertionFailed where
296     showsPrec _ (AssertionFailed err) = showString err
297
298 instance Show AsyncException where
299     showsPrec _ StackOverflow   = showString "stack overflow"
300     showsPrec _ HeapOverflow    = showString "heap overflow"
301     showsPrec _ ThreadKilled    = showString "thread killed"
302     showsPrec _ UserInterrupt   = showString "user interrupt"
303
304 instance Exception BlockedOnDeadMVar
305 instance Exception BlockedIndefinitely
306 instance Exception Deadlock
307 instance Exception AssertionFailed
308 instance Exception AsyncException
309
310 throw :: Exception e => e -> a
311 throw e = Hugs.Exception.throw (toException e)
312
313 throwIO :: Exception e => e -> IO a
314 throwIO e = Hugs.Exception.throwIO (toException e)
315 #endif
316
317 #ifndef __GLASGOW_HASKELL__
318 -- Dummy definitions for implementations lacking asynchonous exceptions
319
320 block   :: IO a -> IO a
321 block    = id
322 unblock :: IO a -> IO a
323 unblock  = id
324 blocked :: IO Bool
325 blocked  = return False
326 #endif
327
328 -----------------------------------------------------------------------------
329 -- Catching exceptions
330
331 -- |This is the simplest of the exception-catching functions.  It
332 -- takes a single argument, runs it, and if an exception is raised
333 -- the \"handler\" is executed, with the value of the exception passed as an
334 -- argument.  Otherwise, the result is returned as normal.  For example:
335 --
336 -- >   catch (openFile f ReadMode)
337 -- >       (\e -> hPutStr stderr ("Couldn't open "++f++": " ++ show e))
338 --
339 -- For catching exceptions in pure (non-'IO') expressions, see the
340 -- function 'evaluate'.
341 --
342 -- Note that due to Haskell\'s unspecified evaluation order, an
343 -- expression may return one of several possible exceptions: consider
344 -- the expression @error \"urk\" + 1 \`div\` 0@.  Does
345 -- 'catch' execute the handler passing
346 -- @ErrorCall \"urk\"@, or @ArithError DivideByZero@?
347 --
348 -- The answer is \"either\": 'catch' makes a
349 -- non-deterministic choice about which exception to catch.  If you
350 -- call it again, you might get a different exception back.  This is
351 -- ok, because 'catch' is an 'IO' computation.
352 --
353 -- Note that 'catch' catches all types of exceptions, and is generally
354 -- used for \"cleaning up\" before passing on the exception using
355 -- 'throwIO'.  It is not good practice to discard the exception and
356 -- continue, without first checking the type of the exception (it
357 -- might be a 'ThreadKilled', for example).  In this case it is usually better
358 -- to use 'catchJust' and select the kinds of exceptions to catch.
359 --
360 -- Also note that the "Prelude" also exports a function called
361 -- 'Prelude.catch' with a similar type to 'Control.Exception.catch',
362 -- except that the "Prelude" version only catches the IO and user
363 -- families of exceptions (as required by Haskell 98).
364 --
365 -- We recommend either hiding the "Prelude" version of 'Prelude.catch'
366 -- when importing "Control.Exception":
367 --
368 -- > import Prelude hiding (catch)
369 --
370 -- or importing "Control.Exception" qualified, to avoid name-clashes:
371 --
372 -- > import qualified Control.Exception as C
373 --
374 -- and then using @C.catch@
375 --
376 #ifndef __NHC__
377 catch   :: Exception e
378         => IO a         -- ^ The computation to run
379         -> (e -> IO a)  -- ^ Handler to invoke if an exception is raised
380         -> IO a
381 #if __GLASGOW_HASKELL__
382 catch = GHC.IOBase.catchException
383 #elif __HUGS__
384 catch m h = Hugs.Exception.catchException m h'
385   where h' e = case fromException e of
386             Just e' -> h e'
387             Nothing -> throwIO e
388 #endif
389 #endif
390
391 -- | The function 'catchJust' is like 'catch', but it takes an extra
392 -- argument which is an /exception predicate/, a function which
393 -- selects which type of exceptions we\'re interested in.
394 --
395 -- >   result <- catchJust errorCalls thing_to_try handler
396 --
397 -- Any other exceptions which are not matched by the predicate
398 -- are re-raised, and may be caught by an enclosing
399 -- 'catch' or 'catchJust'.
400 catchJust
401         :: Exception e
402         => (e -> Maybe b)         -- ^ Predicate to select exceptions
403         -> IO a                   -- ^ Computation to run
404         -> (b -> IO a)            -- ^ Handler
405         -> IO a
406 catchJust p a handler = catch a handler'
407   where handler' e = case p e of
408                         Nothing -> throw e
409                         Just b  -> handler b
410
411 -- | A version of 'catch' with the arguments swapped around; useful in
412 -- situations where the code for the handler is shorter.  For example:
413 --
414 -- >   do handle (\e -> exitWith (ExitFailure 1)) $
415 -- >      ...
416 handle     :: Exception e => (e -> IO a) -> IO a -> IO a
417 handle     =  flip catch
418
419 -- | A version of 'catchJust' with the arguments swapped around (see
420 -- 'handle').
421 handleJust :: Exception e => (e -> Maybe b) -> (b -> IO a) -> IO a -> IO a
422 handleJust p =  flip (catchJust p)
423
424 -----------------------------------------------------------------------------
425 -- 'mapException'
426
427 -- | This function maps one exception into another as proposed in the
428 -- paper \"A semantics for imprecise exceptions\".
429
430 -- Notice that the usage of 'unsafePerformIO' is safe here.
431
432 mapException :: (Exception e1, Exception e2) => (e1 -> e2) -> a -> a
433 mapException f v = unsafePerformIO (catch (evaluate v)
434                                           (\x -> throw (f x)))
435
436 -----------------------------------------------------------------------------
437 -- 'try' and variations.
438
439 -- | Similar to 'catch', but returns an 'Either' result which is
440 -- @('Right' a)@ if no exception was raised, or @('Left' e)@ if an
441 -- exception was raised and its value is @e@.
442 --
443 -- >  try a = catch (Right `liftM` a) (return . Left)
444 --
445 -- Note: as with 'catch', it is only polite to use this variant if you intend
446 -- to re-throw the exception after performing whatever cleanup is needed.
447 -- Otherwise, 'tryJust' is generally considered to be better.
448 --
449 -- Also note that "System.IO.Error" also exports a function called
450 -- 'System.IO.Error.try' with a similar type to 'Control.Exception.try',
451 -- except that it catches only the IO and user families of exceptions
452 -- (as required by the Haskell 98 @IO@ module).
453
454 try :: Exception e => IO a -> IO (Either e a)
455 try a = catch (a >>= \ v -> return (Right v)) (\e -> return (Left e))
456
457 -- | A variant of 'try' that takes an exception predicate to select
458 -- which exceptions are caught (c.f. 'catchJust').  If the exception
459 -- does not match the predicate, it is re-thrown.
460 tryJust :: Exception e => (e -> Maybe b) -> IO a -> IO (Either b a)
461 tryJust p a = do
462   r <- try a
463   case r of
464         Right v -> return (Right v)
465         Left  e -> case p e of
466                         Nothing -> throw e
467                         Just b  -> return (Left b)
468
469 onException :: IO a -> IO b -> IO a
470 onException io what = io `catch` \e -> do what
471                                           throw (e :: SomeException)
472
473 -----------------------------------------------------------------------------
474 -- Some Useful Functions
475
476 -- | When you want to acquire a resource, do some work with it, and
477 -- then release the resource, it is a good idea to use 'bracket',
478 -- because 'bracket' will install the necessary exception handler to
479 -- release the resource in the event that an exception is raised
480 -- during the computation.  If an exception is raised, then 'bracket' will
481 -- re-raise the exception (after performing the release).
482 --
483 -- A common example is opening a file:
484 --
485 -- > bracket
486 -- >   (openFile "filename" ReadMode)
487 -- >   (hClose)
488 -- >   (\handle -> do { ... })
489 --
490 -- The arguments to 'bracket' are in this order so that we can partially apply
491 -- it, e.g.:
492 --
493 -- > withFile name mode = bracket (openFile name mode) hClose
494 --
495 #ifndef __NHC__
496 bracket
497         :: IO a         -- ^ computation to run first (\"acquire resource\")
498         -> (a -> IO b)  -- ^ computation to run last (\"release resource\")
499         -> (a -> IO c)  -- ^ computation to run in-between
500         -> IO c         -- returns the value from the in-between computation
501 bracket before after thing =
502   block (do
503     a <- before
504     r <- unblock (thing a) `onException` after a
505     after a
506     return r
507  )
508 #endif
509
510 -- | A specialised variant of 'bracket' with just a computation to run
511 -- afterward.
512 --
513 finally :: IO a         -- ^ computation to run first
514         -> IO b         -- ^ computation to run afterward (even if an exception
515                         -- was raised)
516         -> IO a         -- returns the value from the first computation
517 a `finally` sequel =
518   block (do
519     r <- unblock a `onException` sequel
520     sequel
521     return r
522   )
523
524 -- | A variant of 'bracket' where the return value from the first computation
525 -- is not required.
526 bracket_ :: IO a -> IO b -> IO c -> IO c
527 bracket_ before after thing = bracket before (const after) (const thing)
528
529 -- | Like bracket, but only performs the final action if there was an
530 -- exception raised by the in-between computation.
531 bracketOnError
532         :: IO a         -- ^ computation to run first (\"acquire resource\")
533         -> (a -> IO b)  -- ^ computation to run last (\"release resource\")
534         -> (a -> IO c)  -- ^ computation to run in-between
535         -> IO c         -- returns the value from the in-between computation
536 bracketOnError before after thing =
537   block (do
538     a <- before
539     unblock (thing a) `onException` after a
540   )
541
542 #if !(__GLASGOW_HASKELL__ || __NHC__)
543 assert :: Bool -> a -> a
544 assert True x = x
545 assert False _ = throw (AssertionFailed "")
546 #endif
547
548 -----
549
550 #if __GLASGOW_HASKELL__ || __HUGS__
551 data PatternMatchFail = PatternMatchFail String
552 INSTANCE_TYPEABLE0(PatternMatchFail,patternMatchFailTc,"PatternMatchFail")
553
554 instance Show PatternMatchFail where
555     showsPrec _ (PatternMatchFail err) = showString err
556
557 #ifdef __HUGS__
558 instance Exception PatternMatchFail where
559     toException (PatternMatchFail err) = Hugs.Exception.PatternMatchFail err
560     fromException (Hugs.Exception.PatternMatchFail err) = Just (PatternMatchFail err)
561     fromException _ = Nothing
562 #else
563 instance Exception PatternMatchFail
564 #endif
565
566 -----
567
568 data RecSelError = RecSelError String
569 INSTANCE_TYPEABLE0(RecSelError,recSelErrorTc,"RecSelError")
570
571 instance Show RecSelError where
572     showsPrec _ (RecSelError err) = showString err
573
574 #ifdef __HUGS__
575 instance Exception RecSelError where
576     toException (RecSelError err) = Hugs.Exception.RecSelError err
577     fromException (Hugs.Exception.RecSelError err) = Just (RecSelError err)
578     fromException _ = Nothing
579 #else
580 instance Exception RecSelError
581 #endif
582
583 -----
584
585 data RecConError = RecConError String
586 INSTANCE_TYPEABLE0(RecConError,recConErrorTc,"RecConError")
587
588 instance Show RecConError where
589     showsPrec _ (RecConError err) = showString err
590
591 #ifdef __HUGS__
592 instance Exception RecConError where
593     toException (RecConError err) = Hugs.Exception.RecConError err
594     fromException (Hugs.Exception.RecConError err) = Just (RecConError err)
595     fromException _ = Nothing
596 #else
597 instance Exception RecConError
598 #endif
599
600 -----
601
602 data RecUpdError = RecUpdError String
603 INSTANCE_TYPEABLE0(RecUpdError,recUpdErrorTc,"RecUpdError")
604
605 instance Show RecUpdError where
606     showsPrec _ (RecUpdError err) = showString err
607
608 #ifdef __HUGS__
609 instance Exception RecUpdError where
610     toException (RecUpdError err) = Hugs.Exception.RecUpdError err
611     fromException (Hugs.Exception.RecUpdError err) = Just (RecUpdError err)
612     fromException _ = Nothing
613 #else
614 instance Exception RecUpdError
615 #endif
616
617 -----
618
619 data NoMethodError = NoMethodError String
620 INSTANCE_TYPEABLE0(NoMethodError,noMethodErrorTc,"NoMethodError")
621
622 instance Show NoMethodError where
623     showsPrec _ (NoMethodError err) = showString err
624
625 #ifdef __HUGS__
626 instance Exception NoMethodError where
627     toException (NoMethodError err) = Hugs.Exception.NoMethodError err
628     fromException (Hugs.Exception.NoMethodError err) = Just (NoMethodError err)
629     fromException _ = Nothing
630 #else
631 instance Exception NoMethodError
632 #endif
633
634 -----
635
636 data NonTermination = NonTermination
637 INSTANCE_TYPEABLE0(NonTermination,nonTerminationTc,"NonTermination")
638
639 instance Show NonTermination where
640     showsPrec _ NonTermination = showString "<<loop>>"
641
642 #ifdef __HUGS__
643 instance Exception NonTermination where
644     toException NonTermination = Hugs.Exception.NonTermination
645     fromException Hugs.Exception.NonTermination = Just NonTermination
646     fromException _ = Nothing
647 #else
648 instance Exception NonTermination
649 #endif
650
651 -----
652
653 data NestedAtomically = NestedAtomically
654 INSTANCE_TYPEABLE0(NestedAtomically,nestedAtomicallyTc,"NestedAtomically")
655
656 instance Show NestedAtomically where
657     showsPrec _ NestedAtomically = showString "Control.Concurrent.STM.atomically was nested"
658
659 instance Exception NestedAtomically
660
661 -----
662
663 instance Exception Dynamic
664
665 #endif /* __GLASGOW_HASKELL__ || __HUGS__ */
666
667 #ifdef __GLASGOW_HASKELL__
668 recSelError, recConError, irrefutPatError, runtimeError,
669              nonExhaustiveGuardsError, patError, noMethodBindingError
670         :: Addr# -> a   -- All take a UTF8-encoded C string
671
672 recSelError              s = throw (RecSelError (unpackCStringUtf8# s)) -- No location info unfortunately
673 runtimeError             s = error (unpackCStringUtf8# s)               -- No location info unfortunately
674
675 nonExhaustiveGuardsError s = throw (PatternMatchFail (untangle s "Non-exhaustive guards in"))
676 irrefutPatError          s = throw (PatternMatchFail (untangle s "Irrefutable pattern failed for pattern"))
677 recConError              s = throw (RecConError      (untangle s "Missing field in record construction"))
678 noMethodBindingError     s = throw (NoMethodError    (untangle s "No instance nor default method for class operation"))
679 patError                 s = throw (PatternMatchFail (untangle s "Non-exhaustive patterns in"))
680
681 -- GHC's RTS calls this
682 nonTermination :: SomeException
683 nonTermination = toException NonTermination
684
685 -- GHC's RTS calls this
686 nestedAtomically :: SomeException
687 nestedAtomically = toException NestedAtomically
688 #endif