1 % -----------------------------------------------------------------------------
2 % $Id: Exception.lhs,v 1.6 1999/03/16 13:20:11 simonm Exp $
4 % (c) The GRAP/AQUA Project, Glasgow University, 1998
7 The External API for exceptions. The functions provided in this
8 module allow catching of exceptions in the IO monad.
13 Exception(..), -- instance Show
14 ArithException(..), -- instance Show
15 AsyncException(..), -- instance Show
17 tryAll, -- :: a -> IO (Either Exception a)
18 tryAllIO, -- :: IO a -> IO (Either Exception a)
19 try, -- :: (Exception -> Maybe b) -> a -> IO (Either b a)
20 tryIO, -- :: (Exception -> Maybe b) -> IO a -> IO (Either b a)
22 catchAll, -- :: a -> (Exception -> IO a) -> IO a
23 catchAllIO,-- :: IO a -> (Exception -> IO a) -> IO a
24 catch, -- :: (Exception -> Maybe b) -> a -> (b -> IO a) -> IO a
25 catchIO, -- :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
27 -- Exception predicates
29 justIoErrors, -- :: Exception -> Maybe IOError
30 justArithExceptions, -- :: Exception -> Maybe ArithException
31 justErrors, -- :: Exception -> Maybe String
32 justDynExceptions, -- :: Exception -> Maybe Dynamic
33 justAssertions, -- :: Exception -> Maybe String
34 justAsyncExceptions, -- :: Exception -> Maybe AsyncException
36 -- Throwing exceptions
38 throw, -- :: Exception -> a
39 raiseInThread, -- :: ThreadId -> Exception -> a
43 throwDyn, -- :: Typeable ex => ex -> b
44 catchDyn, -- :: Typeable ex => IO a -> (ex -> IO a) -> IO a
48 finally, -- :: IO a -> IO b -> IO b
50 bracket, -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
51 bracket_, -- :: IO a -> IO b -> IO c -> IO ()
56 import PreludeBuiltin hiding (catch)
57 import Prelude hiding (catch)
59 import Prelude hiding (catch)
60 import PrelGHC (catch#)
61 import PrelException hiding (catch)
62 import PrelConc ( raiseInThread )
68 -----------------------------------------------------------------------------
71 PrelException defines 'catchException' for us.
74 catchAll :: a -> (Exception -> IO a) -> IO a
76 catchAll a handler = primCatch' (case primForce a of () -> return a) handler
78 catchAll a handler = catch# (a `seq` return a) handler
81 catchAllIO :: IO a -> (Exception -> IO a) -> IO a
82 catchAllIO = catchException
84 catch :: (Exception -> Maybe b) -> a -> (b -> IO a) -> IO a
85 catch p a handler = catchAll a handler'
86 where handler' e = case p e of
90 catchIO :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
91 catchIO p a handler = catchAllIO a handler'
92 where handler' e = case p e of
97 -----------------------------------------------------------------------------
101 tryAll :: a -> IO (Either Exception a)
103 tryAll a = primCatch' (case primForce a of { () -> return Nothing})
104 (\e -> return (Just e))
106 tryAll a = catch# (a `seq` return (Right a)) (\e -> return (Left e))
109 tryAllIO :: IO a -> IO (Either Exception a)
110 tryAllIO a = catchAllIO (a >>= \ v -> return (Right v))
111 (\e -> return (Left e))
113 try :: (Exception -> Maybe b) -> a -> IO (Either b a)
117 Right v -> return (Right v)
118 Left e -> case p e of
120 Just b -> return (Left b)
122 tryIO :: (Exception -> Maybe b) -> IO a -> IO (Either b a)
126 Right v -> return (Right v)
127 Left e -> case p e of
129 Just b -> return (Left b)
132 -----------------------------------------------------------------------------
133 Dynamic exception types. Since one of the possible kinds of exception
134 is a dynamically typed value, we can effectively have polymorphic
137 throwDyn will raise any value as an exception, provided it is in the
138 Typeable class (see Dynamic.lhs).
140 catchDyn will catch any exception of a given type (determined by the
141 handler function). Any raised exceptions that don't match are
145 throwDyn :: Typeable exception => exception -> b
146 throwDyn exception = throw (DynException (toDyn exception))
148 catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
149 catchDyn m k = catchException m handle
150 where handle ex = case ex of
151 (DynException dyn) ->
152 case fromDynamic dyn of
153 Just exception -> k exception
158 -----------------------------------------------------------------------------
162 justIoErrors :: Exception -> Maybe IOError
163 justArithExceptions :: Exception -> Maybe ArithException
164 justErrors :: Exception -> Maybe String
165 justDynExceptions :: Exception -> Maybe Dynamic
166 justAssertions :: Exception -> Maybe String
167 justAsyncExceptions :: Exception -> Maybe AsyncException
169 justIoErrors (IOException e) = Just e
170 justIoErrors _ = Nothing
172 justArithExceptions (ArithException e) = Just e
173 justArithExceptions _ = Nothing
175 justErrors (ErrorCall e) = Just e
176 justErrors _ = Nothing
178 justAssertions (AssertionFailed e) = Just e
179 justAssertions _ = Nothing
181 justDynExceptions (DynException e) = Just e
182 justDynExceptions _ = Nothing
184 justAsyncExceptions (AsyncException e) = Just e
185 justAsyncExceptions _ = Nothing
188 -----------------------------------------------------------------------------
189 Some Useful Functions
192 finally :: IO a -> IO b -> IO b
193 a `finally` sequel = do
197 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
198 bracket before after thing = do
200 c <- tryAllIO (thing a)
206 bracket_ :: IO a -> IO b -> IO c -> IO c
207 bracket_ before after thing = do