catch package:rebase

This is the simplest of the exception-catching functions. It takes a single argument, runs it, and if an exception is raised the "handler" is executed, with the value of the exception passed as an argument. Otherwise, the result is returned as normal. For example:
catch (readFile f)
(\e -> do let err = show (e :: IOException)
hPutStr stderr ("Warning: Couldn't open " ++ f ++ ": " ++ err)
return "")
Note that we have to give a type signature to e, or the program will not typecheck as the type is ambiguous. While it is possible to catch exceptions of any type, see the section "Catching all exceptions" (in Control.Exception) for an explanation of the problems with doing so. For catching exceptions in pure (non-IO) expressions, see the function evaluate. Note that due to Haskell's unspecified evaluation order, an expression may throw one of several possible exceptions: consider the expression (error "urk") + (1 `div` 0). Does the expression throw ErrorCall "urk", or DivideByZero? The answer is "it might throw either"; the choice is non-deterministic. If you are catching any type of exception then you might catch either. If you are calling catch with type IO Int -> (ArithException -> IO Int) -> IO Int then the handler may get run with DivideByZero as an argument, or an ErrorCall "urk" exception may be propagated further up. If you call it again, you might get the opposite behaviour. This is ok, because catch is an IO computation.
A handler function to handle previous errors and return to normal execution. A common idiom is:
do { action1; action2; action3 } `catchError` handler
where the action functions can call throwError. Note that handler and the do-block must have the same return type.
The catchIOError function establishes a handler that receives any IOException raised in the action protected by catchIOError. An IOException is caught by the most recent handler established by one of the exception handling functions. These handlers are not selective: all IOExceptions are caught. Exception propagation must be explicitly provided in a handler by re-raising any unwanted exceptions. For example, in
f = catchIOError g (\e -> if IO.isEOFError e then return [] else ioError e)
the function f returns [] when an end-of-file exception (cf. isEOFError) occurs in g; otherwise, the exception is propagated to the next outer handler. When an exception propagates outside the main program, the Haskell system prints the associated IOException value and exits the program. Non-I/O exceptions are not caught by this variant; to catch all exceptions, use catch from Control.Exception.
The function catchJust is like catch, but it takes an extra argument which is an exception predicate, a function which selects which type of exceptions we're interested in.
catchJust (\e -> if isDoesNotExistErrorType (ioeGetErrorType e) then Just () else Nothing)
(readFile f)
(\_ -> do hPutStrLn stderr ("No such file: " ++ show f)
return "")
Any other exceptions which are not matched by the predicate are re-raised, and may be caught by an enclosing catch, catchJust, etc.
Exception handling within STM actions. catchSTM m f catches any exception thrown by m using throwSTM, using the function f to handle the exception. If an exception is thrown, any changes made by m are rolled back, but changes prior to m persist.
Sometimes you want to catch two different sorts of exception. You could do something like
f = expr `catch` \ (ex :: ArithException) -> handleArith ex
`catch` \ (ex :: IOException)    -> handleIO    ex
However, there are a couple of problems with this approach. The first is that having two exception handlers is inefficient. However, the more serious issue is that the second exception handler will catch exceptions in the first, e.g. in the example above, if handleArith throws an IOException then the second exception handler will catch it. Instead, we provide a function catches, which would be used thus:
f = expr `catches` [Handler (\ (ex :: ArithException) -> handleArith ex),
Handler (\ (ex :: IOException)    -> handleIO    ex)]