try
functions
There are several functions for catching and examining exceptions; all
of them may only be used from within the IO
monad. Firstly the
try
family of functions:
tryAll :: a -> IO (Either Exception a)
tryAllIO :: IO a -> IO (Either Exception a)
try :: (Exception -> Maybe b) -> a -> IO (Either b a)
tryIO :: (Exception -> Maybe b) -> IO a -> IO (Either b a)
The simplest version is tryAll
. It takes a single argument,
evaluates it (as if you'd applied seq
to it), and returns either
Right a
if the evaluation succeeded with result a
, or
Left e
if an exception was raised, where e
is the exception.
Note that due to Haskell's unspecified evaluation order, an expression
may return one of several possible exceptions: consider the expression
error "urk" + 1 `div` 0
. Does tryAll
return Just
(ErrorCall "urk")
or Just (ArithError DivideByZero)
? The answer
is "either": tryAll
makes a non-deterministic choice about which
exception to return. If you call it again, you might get a different
exception back. This is ok, because tryAll
is an IO
computation.
tryAllIO
is the same as tryAll
except that the argument to
evaluate is an IO
computation. Don't try to use tryAll
to
catch exceptions in IO
computations: in GHC an expression of type
IO a
is in fact a function, so evaluating it does nothing at all
(and therefore raises no exceptions). Hence the need for
tryAllIO
, which runs IO
computations properly.
The functions try
and tryIO
take an extra argument which is
an exception predicate, a function which selects which type of
exceptions we're interested in. The full set of exception predicates
is given below:
justIoErrors :: Exception -> Maybe IOError
justArithExceptions :: Exception -> Maybe ArithException
justErrors :: Exception -> Maybe String
justDynExceptions :: Exception -> Maybe Dynamic
justAssertions :: Exception -> Maybe String
justAsyncExceptions :: Exception -> Maybe AsyncException
For example, to catch just calls to 'error' we could use something like
result <- try justErrors thing_to_try
Any other exceptions which aren't matched by the predicate are
re-raised, and may be caught by an enclosing try
or catch
.