Error vs. Exception
(different flavors of 'catch')
(GHC errors and exceptions)
Revision as of 23:55, 5 December 2009
There is confusion about the distinction of errors and exceptions for a long time, repeated threads in Haskell-Cafe and more and more packages that handle errors and exceptions or something between. Although both terms are related and sometimes hard to distinguish, it is important to do it carefully. This is like the confusion between parallelism and concurrency.
The first problem is that exception seem to me to be the historically younger term. Before there were only errors, independent from whether they are programming or I/O or user errors. In this article we want to use the term exception for expected but irregular situations at runtime and the term error for mistakes in the running program, that can be resolved only by fixing the program.
The history may have led to the identifiers we find today in the Haskell language and standard Haskell modules.
- Exceptions: ,Prelude.catch,Control.Exception.catch,Control.Exception.try,IOErrorControl.Monad.Error
- Errors: ,error,Control.Exception.catchDebug.Trace.trace
Prelude> catch (error "bla") (\msg -> putStrLn $ "catched " ++ show msg) *** Exception: bla Prelude> Control.Exception.catch (error "bla") (\msg -> putStrLn $ "catched " ++ show (msg::Control.Exception.SomeException)) catched bla
that shall help spotting a programming error.A program should work as well when all
are replaced by infinite loops.However infinite loops in general cannot be catched, whereas calls to sugared functions like
Even more confusion was initiated by Java programming language
to use the term "exceptions" for programming errors like the
and introducing the distinction between
checked and unchecked exceptions.
error handling = debugging
Let me give some examples for explaining the difference between errors and exceptions and why the distinction is important.
First consider a compiler like GHC. If you feed it with a program that contains syntax or type errors it emits a descriptive message of the problem. For GHC these are exceptions. GHC must expect all of these problems and handles them by generating a useful message for the user. However, sometimes you "succeed" to let GHC emit something like "Panic! This should not happen: ... Write a bug report to firstname.lastname@example.org" Then you encountered a bug in GHC. For GHC this is an error. It cannot be handled by GHC itself. The report "didn't expect TyVar in TyCon after unfolding" or so isn't of much help for the user. It's the business of the GHC developers to fix the problem.
Ok, these are possible reactions to user input. Now a more difficult question: How should GHC handle corruptions in the files it has generated itself like the interface (.hi) and object files (.o)? These corruptions can be introduced easily by the user by editing the files in a simple text editor, or by network problems or by exchanging files between operating systems or different GHC versions, or by virus programs. Thus GHC must be prepared for them, which means, it must generate and handle exceptions here, it must tell the user at least that there is some problem with the read file. Next question: Must GHC also be prepared for corrupt memory or damages in the CPU? Good question. I don't think it must be prepared for that.
User enters number as string, pass to function that expects cardinal
Modula-3 arithmetic library
2 When exceptions become errors
3 When errors become exceptions