Must import ExitCode for its instance to be re-exported.
[ghc-base.git] / Control / Exception.hs
1 {-# OPTIONS_GHC -XNoImplicitPrelude #-}
2
3 -----------------------------------------------------------------------------
4 -- |
5 -- Module      :  Control.Exception
6 -- Copyright   :  (c) The University of Glasgow 2001
7 -- License     :  BSD-style (see the file libraries/base/LICENSE)
8 -- 
9 -- Maintainer  :  libraries@haskell.org
10 -- Stability   :  experimental
11 -- Portability :  non-portable (extended exceptions)
12 --
13 -- This module provides support for raising and catching both built-in
14 -- and user-defined exceptions.
15 --
16 -- In addition to exceptions thrown by 'IO' operations, exceptions may
17 -- be thrown by pure code (imprecise exceptions) or by external events
18 -- (asynchronous exceptions), but may only be caught in the 'IO' monad.
19 -- For more details, see:
20 --
21 --  * /A semantics for imprecise exceptions/, by Simon Peyton Jones,
22 --    Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson,
23 --    in /PLDI'99/.
24 --
25 --  * /Asynchronous exceptions in Haskell/, by Simon Marlow, Simon Peyton
26 --    Jones, Andy Moran and John Reppy, in /PLDI'01/.
27 --
28 -----------------------------------------------------------------------------
29
30 module Control.Exception (
31
32         -- * The Exception type
33 #ifdef __HUGS__
34         SomeException,
35 #else
36         SomeException(..),
37 #endif
38         Exception(..),          -- instance Eq, Ord, Show, Typeable
39         IOException,            -- instance Eq, Ord, Show, Typeable
40         ArithException(..),     -- instance Eq, Ord, Show, Typeable
41         ArrayException(..),     -- instance Eq, Ord, Show, Typeable
42         AssertionFailed(..),
43         AsyncException(..),     -- instance Eq, Ord, Show, Typeable
44
45 #if __GLASGOW_HASKELL__ || __HUGS__
46         NonTermination(..),
47         NestedAtomically(..),
48 #endif
49 #ifdef __NHC__
50         System.ExitCode(),      -- instance Exception
51 #endif
52
53         BlockedOnDeadMVar(..),
54         BlockedIndefinitely(..),
55         Deadlock(..),
56         NoMethodError(..),
57         PatternMatchFail(..),
58         RecConError(..),
59         RecSelError(..),
60         RecUpdError(..),
61         ErrorCall(..),
62
63         -- * Throwing exceptions
64         throwIO,        -- :: Exception -> IO a
65         throw,          -- :: Exception -> a
66         ioError,        -- :: IOError -> IO a
67 #ifdef __GLASGOW_HASKELL__
68         throwTo,        -- :: ThreadId -> Exception -> a
69 #endif
70
71         -- * Catching Exceptions
72
73         -- |There are several functions for catching and examining
74         -- exceptions; all of them may only be used from within the
75         -- 'IO' monad.
76
77         -- ** The @catch@ functions
78         catch,     -- :: IO a -> (Exception -> IO a) -> IO a
79 #if __GLASGOW_HASKELL__ || __HUGS__
80         catches, Handler(..),
81 #endif
82         catchJust, -- :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
83
84         -- ** The @handle@ functions
85         handle,    -- :: (Exception -> IO a) -> IO a -> IO a
86         handleJust,-- :: (Exception -> Maybe b) -> (b -> IO a) -> IO a -> IO a
87
88         -- ** The @try@ functions
89         try,       -- :: IO a -> IO (Either Exception a)
90         tryJust,   -- :: (Exception -> Maybe b) -> a    -> IO (Either b a)
91         onException,
92
93         -- ** The @evaluate@ function
94         evaluate,  -- :: a -> IO a
95
96         -- ** The @mapException@ function
97         mapException,           -- :: (Exception -> Exception) -> a -> a
98
99         -- * Asynchronous Exceptions
100
101         -- $async
102
103         -- ** Asynchronous exception control
104
105         -- |The following two functions allow a thread to control delivery of
106         -- asynchronous exceptions during a critical region.
107
108         block,          -- :: IO a -> IO a
109         unblock,        -- :: IO a -> IO a
110         blocked,        -- :: IO Bool
111
112         -- *** Applying @block@ to an exception handler
113
114         -- $block_handler
115
116         -- *** Interruptible operations
117
118         -- $interruptible
119
120         -- * Assertions
121
122         assert,         -- :: Bool -> a -> a
123
124         -- * Utilities
125
126         bracket,        -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
127         bracket_,       -- :: IO a -> IO b -> IO c -> IO ()
128         bracketOnError,
129
130         finally,        -- :: IO a -> IO b -> IO a
131   ) where
132
133 import Control.Exception.Base
134
135 #ifdef __GLASGOW_HASKELL__
136 import GHC.Base
137 import GHC.IOBase
138 import Data.Maybe
139 #else
140 import Prelude hiding (catch)
141 #endif
142
143 #ifdef __NHC__
144 import System (ExitCode())
145 #endif
146
147 #if __GLASGOW_HASKELL__ || __HUGS__
148 data Handler a = forall e . Exception e => Handler (e -> IO a)
149
150 catches :: IO a -> [Handler a] -> IO a
151 catches io handlers = io `catch` catchesHandler handlers
152
153 catchesHandler :: [Handler a] -> SomeException -> IO a
154 catchesHandler handlers e = foldr tryHandler (throw e) handlers
155     where tryHandler (Handler handler) res
156               = case fromException e of
157                 Just e' -> handler e'
158                 Nothing -> res
159 #endif
160
161 -- -----------------------------------------------------------------------------
162 -- Asynchronous exceptions
163
164 {- $async
165
166  #AsynchronousExceptions# Asynchronous exceptions are so-called because they arise due to
167 external influences, and can be raised at any point during execution.
168 'StackOverflow' and 'HeapOverflow' are two examples of
169 system-generated asynchronous exceptions.
170
171 The primary source of asynchronous exceptions, however, is
172 'throwTo':
173
174 >  throwTo :: ThreadId -> Exception -> IO ()
175
176 'throwTo' (also 'throwDynTo' and 'Control.Concurrent.killThread') allows one
177 running thread to raise an arbitrary exception in another thread.  The
178 exception is therefore asynchronous with respect to the target thread,
179 which could be doing anything at the time it receives the exception.
180 Great care should be taken with asynchronous exceptions; it is all too
181 easy to introduce race conditions by the over zealous use of
182 'throwTo'.
183 -}
184
185 {- $block_handler
186 There\'s an implied 'block' around every exception handler in a call
187 to one of the 'catch' family of functions.  This is because that is
188 what you want most of the time - it eliminates a common race condition
189 in starting an exception handler, because there may be no exception
190 handler on the stack to handle another exception if one arrives
191 immediately.  If asynchronous exceptions are blocked on entering the
192 handler, though, we have time to install a new exception handler
193 before being interrupted.  If this weren\'t the default, one would have
194 to write something like
195
196 >      block (
197 >           catch (unblock (...))
198 >                      (\e -> handler)
199 >      )
200
201 If you need to unblock asynchronous exceptions again in the exception
202 handler, just use 'unblock' as normal.
203
204 Note that 'try' and friends /do not/ have a similar default, because
205 there is no exception handler in this case.  If you want to use 'try'
206 in an asynchronous-exception-safe way, you will need to use
207 'block'.
208 -}
209
210 {- $interruptible
211
212 Some operations are /interruptible/, which means that they can receive
213 asynchronous exceptions even in the scope of a 'block'.  Any function
214 which may itself block is defined as interruptible; this includes
215 'Control.Concurrent.MVar.takeMVar'
216 (but not 'Control.Concurrent.MVar.tryTakeMVar'),
217 and most operations which perform
218 some I\/O with the outside world.  The reason for having
219 interruptible operations is so that we can write things like
220
221 >      block (
222 >         a <- takeMVar m
223 >         catch (unblock (...))
224 >               (\e -> ...)
225 >      )
226
227 if the 'Control.Concurrent.MVar.takeMVar' was not interruptible,
228 then this particular
229 combination could lead to deadlock, because the thread itself would be
230 blocked in a state where it can\'t receive any asynchronous exceptions.
231 With 'Control.Concurrent.MVar.takeMVar' interruptible, however, we can be
232 safe in the knowledge that the thread can receive exceptions right up
233 until the point when the 'Control.Concurrent.MVar.takeMVar' succeeds.
234 Similar arguments apply for other interruptible operations like
235 'System.IO.openFile'.
236 -}