1 -----------------------------------------------------------------------------
3 -- Module : Control.Exception
4 -- Copyright : (c) The University of Glasgow 2001
5 -- License : BSD-style (see the file libraries/core/LICENSE)
7 -- Maintainer : libraries@haskell.org
8 -- Stability : experimental
9 -- Portability : non-portable
11 -- The External API for exceptions. The functions provided in this
12 -- module allow catching of exceptions in the IO monad.
14 -----------------------------------------------------------------------------
16 module Control.Exception (
18 Exception(..), -- instance Eq, Ord, Show, Typeable
19 IOException, -- instance Eq, Ord, Show, Typeable
20 ArithException(..), -- instance Eq, Ord, Show, Typeable
21 ArrayException(..), -- instance Eq, Ord, Show, Typeable
22 AsyncException(..), -- instance Eq, Ord, Show, Typeable
24 try, -- :: IO a -> IO (Either Exception a)
25 tryJust, -- :: (Exception -> Maybe b) -> a -> IO (Either b a)
27 catch, -- :: IO a -> (Exception -> IO a) -> IO a
28 catchJust, -- :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
30 handle, -- :: (Exception -> IO a) -> IO a -> IO a
31 handleJust,-- :: (Exception -> Maybe b) -> (b -> IO a) -> IO a -> IO a
33 evaluate, -- :: a -> IO a
35 -- Exception predicates (for tryJust, catchJust, handleJust)
37 ioErrors, -- :: Exception -> Maybe IOError
38 arithExceptions, -- :: Exception -> Maybe ArithException
39 errorCalls, -- :: Exception -> Maybe String
40 dynExceptions, -- :: Exception -> Maybe Dynamic
41 assertions, -- :: Exception -> Maybe String
42 asyncExceptions, -- :: Exception -> Maybe AsyncException
43 userErrors, -- :: Exception -> Maybe String
45 -- Throwing exceptions
47 throw, -- :: Exception -> a
48 throwTo, -- :: ThreadId -> Exception -> a
52 throwDyn, -- :: Typeable ex => ex -> b
53 throwDynTo, -- :: Typeable ex => ThreadId -> ex -> b
54 catchDyn, -- :: Typeable ex => IO a -> (ex -> IO a) -> IO a
56 -- Async exception control
58 block, -- :: IO a -> IO a
59 unblock, -- :: IO a -> IO a
64 assert, -- :: Bool -> a -> a
68 finally, -- :: IO a -> IO b -> IO b
70 bracket, -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
71 bracket_, -- :: IO a -> IO b -> IO c -> IO ()
75 #ifdef __GLASGOW_HASKELL__
76 import Prelude hiding (catch)
77 import System.IO.Error
78 import GHC.Base ( assert )
79 import GHC.Exception hiding (try, catch, bracket, bracket_)
80 import GHC.Conc ( throwTo, ThreadId )
81 import GHC.IOBase ( IO(..) )
85 import Prelude hiding ( catch )
86 import PrelPrim ( catchException
98 INSTANCE_TYPEABLE0(Exception,exceptionTc,"Exception")
99 INSTANCE_TYPEABLE0(IOException,ioExceptionTc,"IOException")
100 INSTANCE_TYPEABLE0(ArithException,arithExceptionTc,"ArithException")
101 INSTANCE_TYPEABLE0(ArrayException,arrayExceptionTc,"ArrayException")
102 INSTANCE_TYPEABLE0(AsyncException,asyncExceptionTc,"AsyncException")
104 -----------------------------------------------------------------------------
105 -- Catching exceptions
107 -- GHC.Exception defines 'catchException' for us.
109 catch :: IO a -> (Exception -> IO a) -> IO a
110 catch = catchException
112 catchJust :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
113 catchJust p a handler = catch a handler'
114 where handler' e = case p e of
118 handle :: (Exception -> IO a) -> IO a -> IO a
121 handleJust :: (Exception -> Maybe b) -> (b -> IO a) -> IO a -> IO a
122 handleJust p = flip (catchJust p)
124 -----------------------------------------------------------------------------
127 evaluate :: a -> IO a
128 evaluate a = a `seq` return a
130 -----------------------------------------------------------------------------
131 -- 'try' and variations.
133 try :: IO a -> IO (Either Exception a)
134 try a = catch (a >>= \ v -> return (Right v)) (\e -> return (Left e))
136 tryJust :: (Exception -> Maybe b) -> IO a -> IO (Either b a)
140 Right v -> return (Right v)
141 Left e -> case p e of
143 Just b -> return (Left b)
145 -----------------------------------------------------------------------------
146 -- Dynamic exception types. Since one of the possible kinds of exception
147 -- is a dynamically typed value, we can effectively have polymorphic
150 -- throwDyn will raise any value as an exception, provided it is in the
151 -- Typeable class (see Dynamic.lhs).
153 -- catchDyn will catch any exception of a given type (determined by the
154 -- handler function). Any raised exceptions that don't match are
157 throwDyn :: Typeable exception => exception -> b
158 throwDyn exception = throw (DynException (toDyn exception))
160 throwDynTo :: Typeable exception => ThreadId -> exception -> IO ()
161 throwDynTo t exception = throwTo t (DynException (toDyn exception))
163 catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
164 catchDyn m k = catchException m handle
165 where handle ex = case ex of
166 (DynException dyn) ->
167 case fromDynamic dyn of
168 Just exception -> k exception
172 -----------------------------------------------------------------------------
173 -- Exception Predicates
175 ioErrors :: Exception -> Maybe IOError
176 arithExceptions :: Exception -> Maybe ArithException
177 errorCalls :: Exception -> Maybe String
178 dynExceptions :: Exception -> Maybe Dynamic
179 assertions :: Exception -> Maybe String
180 asyncExceptions :: Exception -> Maybe AsyncException
181 userErrors :: Exception -> Maybe String
183 ioErrors e@(IOException _) = Just e
186 arithExceptions (ArithException e) = Just e
187 arithExceptions _ = Nothing
189 errorCalls (ErrorCall e) = Just e
190 errorCalls _ = Nothing
192 assertions (AssertionFailed e) = Just e
193 assertions _ = Nothing
195 dynExceptions (DynException e) = Just e
196 dynExceptions _ = Nothing
198 asyncExceptions (AsyncException e) = Just e
199 asyncExceptions _ = Nothing
201 userErrors e | isUserError e = Just (ioeGetErrorString e)
202 userErrors _ = Nothing
204 -----------------------------------------------------------------------------
205 -- Some Useful Functions
207 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
208 bracket before after thing =
213 (\e -> do { after a; throw e })
218 -- finally is an instance of bracket, but it's quite common
219 -- so we give the specialised version for efficiency.
220 finally :: IO a -> IO b -> IO a
225 (\e -> do { sequel; throw e })
230 bracket_ :: IO a -> IO b -> IO c -> IO c
231 bracket_ before after thing = bracket before (const after) (const thing)