440197695db1b5a041481440738b577ecd717215
[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
50         BlockedOnDeadMVar(..),
51         BlockedIndefinitely(..),
52         Deadlock(..),
53         NoMethodError(..),
54         PatternMatchFail(..),
55         RecConError(..),
56         RecSelError(..),
57         RecUpdError(..),
58         ErrorCall(..),
59
60         -- * Throwing exceptions
61         throwIO,        -- :: Exception -> IO a
62         throw,          -- :: Exception -> a
63         ioError,        -- :: IOError -> IO a
64 #ifdef __GLASGOW_HASKELL__
65         throwTo,        -- :: ThreadId -> Exception -> a
66 #endif
67
68         -- * Catching Exceptions
69
70         -- |There are several functions for catching and examining
71         -- exceptions; all of them may only be used from within the
72         -- 'IO' monad.
73
74         -- ** The @catch@ functions
75         catch,     -- :: IO a -> (Exception -> IO a) -> IO a
76 #if __GLASGOW_HASKELL__ || __HUGS__
77         catches, Handler(..),
78 #endif
79         catchJust, -- :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
80
81         -- ** The @handle@ functions
82         handle,    -- :: (Exception -> IO a) -> IO a -> IO a
83         handleJust,-- :: (Exception -> Maybe b) -> (b -> IO a) -> IO a -> IO a
84
85         -- ** The @try@ functions
86         try,       -- :: IO a -> IO (Either Exception a)
87         tryJust,   -- :: (Exception -> Maybe b) -> a    -> IO (Either b a)
88         onException,
89
90         -- ** The @evaluate@ function
91         evaluate,  -- :: a -> IO a
92
93         -- ** The @mapException@ function
94         mapException,           -- :: (Exception -> Exception) -> a -> a
95
96         -- * Asynchronous Exceptions
97
98         -- $async
99
100         -- ** Asynchronous exception control
101
102         -- |The following two functions allow a thread to control delivery of
103         -- asynchronous exceptions during a critical region.
104
105         block,          -- :: IO a -> IO a
106         unblock,        -- :: IO a -> IO a
107         blocked,        -- :: IO Bool
108
109         -- *** Applying @block@ to an exception handler
110
111         -- $block_handler
112
113         -- *** Interruptible operations
114
115         -- $interruptible
116
117         -- * Assertions
118
119         assert,         -- :: Bool -> a -> a
120
121         -- * Utilities
122
123         bracket,        -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
124         bracket_,       -- :: IO a -> IO b -> IO c -> IO ()
125         bracketOnError,
126
127         finally,        -- :: IO a -> IO b -> IO a
128   ) where
129
130 import Control.Exception.Base
131
132 #ifdef __GLASGOW_HASKELL__
133 import GHC.Base
134 import GHC.IOBase
135 import Data.Maybe
136 #else
137 import Prelude hiding (catch)
138 #endif
139
140 #if __GLASGOW_HASKELL__ || __HUGS__
141 data Handler a = forall e . Exception e => Handler (e -> IO a)
142
143 catches :: IO a -> [Handler a] -> IO a
144 catches io handlers = io `catch` catchesHandler handlers
145
146 catchesHandler :: [Handler a] -> SomeException -> IO a
147 catchesHandler handlers e = foldr tryHandler (throw e) handlers
148     where tryHandler (Handler handler) res
149               = case fromException e of
150                 Just e' -> handler e'
151                 Nothing -> res
152 #endif
153
154 -- -----------------------------------------------------------------------------
155 -- Asynchronous exceptions
156
157 {- $async
158
159  #AsynchronousExceptions# Asynchronous exceptions are so-called because they arise due to
160 external influences, and can be raised at any point during execution.
161 'StackOverflow' and 'HeapOverflow' are two examples of
162 system-generated asynchronous exceptions.
163
164 The primary source of asynchronous exceptions, however, is
165 'throwTo':
166
167 >  throwTo :: ThreadId -> Exception -> IO ()
168
169 'throwTo' (also 'throwDynTo' and 'Control.Concurrent.killThread') allows one
170 running thread to raise an arbitrary exception in another thread.  The
171 exception is therefore asynchronous with respect to the target thread,
172 which could be doing anything at the time it receives the exception.
173 Great care should be taken with asynchronous exceptions; it is all too
174 easy to introduce race conditions by the over zealous use of
175 'throwTo'.
176 -}
177
178 {- $block_handler
179 There\'s an implied 'block' around every exception handler in a call
180 to one of the 'catch' family of functions.  This is because that is
181 what you want most of the time - it eliminates a common race condition
182 in starting an exception handler, because there may be no exception
183 handler on the stack to handle another exception if one arrives
184 immediately.  If asynchronous exceptions are blocked on entering the
185 handler, though, we have time to install a new exception handler
186 before being interrupted.  If this weren\'t the default, one would have
187 to write something like
188
189 >      block (
190 >           catch (unblock (...))
191 >                      (\e -> handler)
192 >      )
193
194 If you need to unblock asynchronous exceptions again in the exception
195 handler, just use 'unblock' as normal.
196
197 Note that 'try' and friends /do not/ have a similar default, because
198 there is no exception handler in this case.  If you want to use 'try'
199 in an asynchronous-exception-safe way, you will need to use
200 'block'.
201 -}
202
203 {- $interruptible
204
205 Some operations are /interruptible/, which means that they can receive
206 asynchronous exceptions even in the scope of a 'block'.  Any function
207 which may itself block is defined as interruptible; this includes
208 'Control.Concurrent.MVar.takeMVar'
209 (but not 'Control.Concurrent.MVar.tryTakeMVar'),
210 and most operations which perform
211 some I\/O with the outside world.  The reason for having
212 interruptible operations is so that we can write things like
213
214 >      block (
215 >         a <- takeMVar m
216 >         catch (unblock (...))
217 >               (\e -> ...)
218 >      )
219
220 if the 'Control.Concurrent.MVar.takeMVar' was not interruptible,
221 then this particular
222 combination could lead to deadlock, because the thread itself would be
223 blocked in a state where it can\'t receive any asynchronous exceptions.
224 With 'Control.Concurrent.MVar.takeMVar' interruptible, however, we can be
225 safe in the knowledge that the thread can receive exceptions right up
226 until the point when the 'Control.Concurrent.MVar.takeMVar' succeeds.
227 Similar arguments apply for other interruptible operations like
228 'System.IO.openFile'.
229 -}