There are too many error handling conventions used in library code!

Robert Dockins robdockins at fastmail.fm
Sun Mar 11 11:22:31 EDT 2007


On Sunday 11 March 2007 09:13, Eric Kidd wrote:
> Donald Bruce Stewart <dons <at> cse.unsw.edu.au> writes:
> > The lack of consistent error reporting between libs results in verbose
> > code, as we're not able to use a single error handling technique when
> > gluing together code from different libs (i.e. we can't just use Maybe
> > or Either/ErrorT).

[snip]

> An ideal error-reporting convention would have several properties:
>
> a) Provide a way to report "assertion failures" from any kind of code.
> These errors never should have happened, but cropped up anyway, so they
> aren't worth cluttering the API to think about.  The existing 'error'
> function serves this purpose admirably.
>
> b) Provide a way to say, "You know that thing you just asked for? It
> doesn't exist" (e.g., Data.Map.lookup). The current convention of using
> Monad/fail is an admirable solution, because it integrates into whatever
> error-reporting style the caller is currently using.
>
> c) Provide a unified way to deal with the error ADTs defined by libraries,
> e.g., ConnError, ParseError, etc. At the moment, this is pretty
> non-trivial: You need to either smash everything down to a string, or use
> something hairy, such as '(Error e, Typeable e) => Either e a'. This is
> where novice Haskell programmers are most likely to wind up in trouble.
>
> d) Provide a way to deal with errors in mixed functional/IO-based code. It
> would be especially nice to have lifting functions that converted
> Either/ErrorT-based errors into the exceptions used in the IO monad.
>
> I think the current solutions for (a) and (b) are great, but (c) and (d)
> often frustrate me.
>
> >     * can we identify error handling strategies from the list that should
> >     not be used anymore? (throwDyn?)
>
> One point I made earlier about throwDyn: Out of the 8 error-handling
> strategies, throwDyn is the only one that can mix ConnError and ParseError
> in a reasonably seemless fashion. I'm not saying that programmers should
> use throwDyn; just that it's the only approach which really handles (c)
> above. And even then, it only works in the IO monad.

I think you are largely right.  (c) especially seems to be a weak point.

One option that strikes me as a possibility is to add an (Error Dynamic) 
instance and use (MonadError Dynamic).  This has the advantages of 'throwDyn' 
without tying it to the IO monad.  Together with a suite of lifting 
functions, you could (as a library consumer) integrate almost any error 
handling convention into a single monad, leaving the ugliness of handling 
various error representations to the error handling code, where it belongs.

Alternately, one could build an ErrorDyn monad directly and avoid the issue of 
MPTC+FDs that MonadError has.


> > can we make precise recommendations about which error strategies to use?
>
> As an aspiring Haskell library author, I crave guidance. :-)
>
> Thank you to everyone who's interested in this topic!
>
> Cheers,
> Eric


More information about the Libraries mailing list