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:
- Composition can be achieved by "wrapping" the exceptions. For example,
data FileError = FileNotFound | FileHandleLocked
can be wrapped asdata AppError = DbError | OtherError FileError
. Not very elegant, but works well enough in simple cases. All it takes is one helper function. - 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. - 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