Sunday 21 August 2016

Nothing's wrong with ExceptT IO

ExceptT, quoted from the mtl library: Computations which may fail or throw exceptions.

I recently came across this post, which advocates against the use of ExceptT in an IO-based monad.

The 3 reasons do sound very convincing, but alas I believe it is a matter of taste:

  1. Composition can be achieved by "wrapping" the exceptions. For example, data FileError = FileNotFound | FileHandleLocked can be wrapped as data AppError = DbError | OtherError FileError. Not very elegant, but works well enough in simple cases. All it takes is one helper function.
  2. This is essentially a debate about checked and unchecked exceptions. The good thing about checked exceptions - ExceptT IO - are they are self documenting. The bad thing about is that it is necessarily more verbose.
  3. Checked exceptions forces errors to be handled at this layer (when unwrapping the ExceptT), or at least be manually re-thrown.

I use ExceptT IO regularly, especially in HTTP handlers, because they let me alter control flow easily. Regular exceptions (throw from Control.Exception) work too, but some conditions that are easily recoverable don't seem to warrant their use, semantically. Just a personal feeling.

For example, if an important form parameter was left empty, is it an "exception" in the sense of being unexpected? Or is it a computation (HTTP request) that has failed, and deserves a 400?

Summary: I use ExceptT IO, haven't faced any problems so far, and believes it's a perfectly fine pattern.

No comments:

Post a Comment