Skip to content
Provides API for enriching errors with contexts
Haskell
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src/Control/Error
test
.gitignore
.travis.yml
ChangeLog.md
LICENSE
README.md
Setup.hs
package.yaml
stack.yaml

README.md

error-context Hackage version Stackage version Build Status

!! 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 KatipContext monads.

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 catch- and try-functions are provided for accessing these contexts.

How to use it?

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.

Examples

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?

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 -> 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 throw.

You can’t perform that action at this time.