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
KatipContext monads.
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
catch- and try-functions are provided for accessing these
contexts.
Add an ErrorContextT layer to your monad transformer stack by adding
runErrorContextT to the transformer unwrapping code.
The ErrorContextT transformer provides the context-enriching logic
via special implementations of MonadThrow, MonadCatch and
MonadIO.
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 $ errWithCtxWhen 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.
The ErrorContextT transformer implements MonadThrow and MonadIO,
therefore exceptions thrown by throwM and via liftIO are
automatically context-enriched. On the other hand, exceptional values
created via
throw :: Exception e => e -> aare not context-enriched per se. But there is a workaround for this use-case:
ensureExceptionContext :: (MonadCatch m, MonadErrorContext m) => m a -> m aThis function provides context-aware enriching for any exceptions
thrown within some monadic value, including those thrown by evaluating
values created by throw.