2 <label id="sec:Exception">
5 The Exception library provides an interface for raising and catching
6 both built-in and user defined exceptions.
8 Exceptions are defined by the following (non-abstract) datatype:
12 = IOException IOError -- IO exceptions (from 'fail')
13 | ArithException ArithException -- Arithmetic exceptions
14 | ErrorCall String -- Calls to 'error'
15 | NoMethodError String -- A non-existent method was invoked
16 | PatternMatchFail String -- A pattern match failed
17 | NonExhaustiveGuards String -- A guard match failed
18 | RecSelError String -- Selecting a non-existent field
19 | RecConError String -- Field missing in record construction
20 | RecUpdError String -- Record doesn't contain updated field
21 | AssertionFailed String -- Assertions
22 | DynException Dynamic -- Dynamic exceptions
23 | AsyncException AsyncException -- Externally generated errors
26 instance Ord Exception
27 instance Show Exception
36 instance Eq ArithError
37 instance Ord ArithError
38 instance Show ArithError
46 instance Eq AsyncException
47 instance Ord AsyncException
48 instance Show AsyncException
51 An implementation should raise the appropriate exception when one of
52 the above conditions arises. <em>Note: GHC currently doesn't generate
53 the arithmetic or the async exceptions.</em>
55 Exceptions may be thrown explicitly from anywhere:
58 throw :: Exception -> a
61 <sect1> The <tt/try/ functions
64 There are several functions for catching and examining exceptions; all
65 of them may only be used from within the <tt/IO/ monad. Firstly the
66 <tt/try/ family of functions:
69 tryAll :: a -> IO (Either Exception a)
70 tryAllIO :: IO a -> IO (Either Exception a)
71 try :: (Exception -> Maybe b) -> a -> IO (Either b a)
72 tryIO :: (Exception -> Maybe b) -> IO a -> IO (Either b a)
75 The simplest version is <tt/tryAll/. It takes a single argument,
76 evaluates it (as if you'd applied <tt/seq/ to it), and returns either
77 <tt/Right a/ if the evaluation succeeded with result <tt/a/, or
78 <tt/Left e/ if an exception was raised, where <tt/e/ is the exception.
79 Note that due to Haskell's unspecified evaluation order, an expression
80 may return one of several possible exceptions: consider the expression
81 <tt/error "urk" + 1 `div` 0/. Does <tt/tryAll/ return <tt/Just
82 (ErrorCall "urk")/ or <tt/Just (ArithError DivideByZero)/? The answer
83 is "either": <tt/tryAll/ makes a non-deterministic choice about which
84 exception to return. If you call it again, you might get a different
85 exception back. This is ok, because <tt/tryAll/ is an IO
88 <tt/tryAllIO/ is the same as <tt/tryAll/ except that the argument to
89 evaluate is an <tt/IO/ computation. Don't try to use <tt/tryAll/ to
90 catch exceptions in <tt/IO/ computations: in GHC an expression of type
91 <tt/IO a/ is in fact a function, so evaluating it does nothing at all
92 (and therefore raises no exceptions). Hence the need for
93 <tt/tryAllIO/, which runs <tt/IO/ computations properly.
95 The functions <tt/try/ and <tt/tryIO/ take an extra argument which is
96 an <em/exception predicate/, a function which selects which type of
97 exceptions we're interested in. The full set of exception predicates
101 justIoErrors :: Exception -> Maybe IOError
102 justArithExceptions :: Exception -> Maybe ArithException
103 justErrors :: Exception -> Maybe String
104 justDynExceptions :: Exception -> Maybe Dynamic
105 justAssertions :: Exception -> Maybe String
106 justAsyncExceptions :: Exception -> Maybe AsyncException
109 For example, to catch just calls to 'error' we could use something
113 result <- try justErrors thing_to_try
116 Any other exceptions which aren't matched by the predicate are
117 re-raised, and may be caught by an enclosing <tt/try/ or <tt/catch/.
119 <sect1> The <tt/catch/ functions
122 The <tt/catch/ family is similar to the <tt/try/ family:
125 catchAll :: a -> (Exception -> IO a) -> IO a
126 catchAllIO :: IO a -> (Exception -> IO a) -> IO a
127 catch :: (Exception -> Maybe b) -> a -> (b -> IO a) -> IO a
128 catchIO :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
131 The difference is that instead of returning an <tt/Either/ type as the
132 result, the <tt/catch/ functions take a <em/handler/ argument which is
133 invoked in the case that an exception was raised while evaluating the
136 <tt/catch/ and <tt/catchIO/ take exception predicate arguments in the
137 same way as <tt/try/ and <tt/tryIO/.
139 Note that <tt/catchIO justIoErrors/ is identical to <tt/IO.catch/. In
140 fact, the implementation of <tt/IO/ errors in GHC uses exceptions
143 Also, don't forget to <tt/import Prelude hidiing (catch)/ when using
144 this library, to avoid the name clash between <tt/Exception.catch/ and
147 <sect1> <idx/Dynamic Exceptions/
148 <label id="sec:Dynamic-Exceptions">
151 Because the <tt/Exception/ datatype isn't extendible, we added an
152 interface for throwing and catching exceptions of type <tt/Dynamic/
153 (see Section <ref name="Dynamic" id="sec:Dynamic">), which allows
154 exception values of any type in the <tt/Typeable/ class to be thrown
158 throwDyn :: Typeable exception => exception -> b
159 catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
162 The <tt/catchDyn/ function only catches exceptions of the required
163 type; all other exceptions are re-thrown as with <tt/catchIO/ and
166 <sect1> Other Utilities
169 The <tt/bracket/ functions are useful for making sure that resources are
170 released properly by code that may raise exceptions:
173 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
174 bracket_ :: IO a -> IO b -> IO c -> IO c
175 finally :: IO a -> IO b -> IO b
178 For example, to open a file, do some work on it and then close it
179 again, we might use something like:
182 process_file = bracket (openFile "filename") closeFile
188 <tt/bracket/ works as follows: it executes its first argument
189 ("open"), then its third argument, followed finally by its second
190 argument ("close"). If the third argument happened to raise an
191 exception, then the close operation will still be performed, and the
192 exception will be re-raised.
194 This means that in the example above the file will always be closed,
195 even if an error occurs during processing.
197 The arguments to <tt/bracket/ are in this order so that we can
198 partially apply it, like:
201 withFile name = bracket (openFile name) closeFile
204 The <tt/bracket_/ function is a variant of <tt/bracket/ that throws
205 away the result of the open, and <tt/finally/ is an even simpler
206 version where we just want some closing code.