!! This is experimental work-in-progress !!
Welcome to error-context! This is a library providing context-aware
error and exception handling for Haskell. It has built-in support for
the Katip logging
package. This means that
in combination with Katip, error-context can transparently use the
context (key-value pairs and namespace hierarchy) maintained by
What problem does error-context attempt to solve?
Good error handling is hard. In the case of failures it is important to keep as much context as necessary for a proper problem analysis. Call traces sometimes help, but the current solutions in Haskell-land for accessing call traces are rather limited.
The error-context library allows you to easily attach call traces
('error contexts') to errors, in particular to exceptions. Special
try-functions are provided for accessing these
How to use it?
ErrorContextT layer to your monad transformer stack by adding
runErrorContextT to the transformer unwrapping code.
ErrorContextT transformer provides the context-enriching logic
via special implementations of
Consider this IO action:
testExample :: IO () testExample = do Left errWithCtx :: Either (ErrorWithContext SomeException) () <- try . runErrorContextT $ withErrorNamespace "middle-earth" $ withErrorNamespace "mordor" $ withErrorContext "ring-carrier" ("Frodo" :: Text) $ throwM TestException putStrLn . displayException $ errWithCtx
When run, it produces the following output:
Exception: TestException ring-carrier: "Frodo" caused by: mordor caused by: middle-earth
For more examples, see https://github.com/mtesseract/error-context/blob/master/test/Control/Error/Context/Test.hs.
What about "pure" exceptions?
ErrorContextT transformer implements
therefore exceptions thrown by
throwM and via
automatically context-enriched. On the other hand, exceptional values
throw :: Exception e => e -> a
are not context-enriched per se. But there is a workaround for this use-case:
ensureExceptionContext :: (MonadCatch m, MonadErrorContext m) => m a -> m a
This function provides context-aware enriching for any exceptions
thrown within some monadic value, including those thrown by evaluating
values created by