packages feed

error-context-0.2.0.0: README.md

# error-context [![Hackage version](https://img.shields.io/hackage/v/error-context.svg?label=Hackage)](https://hackage.haskell.org/package/error-context) [![Stackage version](https://www.stackage.org/package/error-context/badge/lts?label=Stackage)](https://www.stackage.org/package/error-context) [![Build Status](https://travis-ci.org/mtesseract/error-context.svg?branch=master)](https://travis-ci.org/mtesseract/error-context)

# !! 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](https://hackage.haskell.org/package/katip). 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:

```haskell
testExample :: IO ()
testExample = do
  Left errWithCtx <- tryAnyWithContext . runErrorContextT $ do
    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: middle-earth
  caused by: mordor
```

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

```haskell
throw :: Exception e => e -> a
```

are not context-enriched per se. But there is a workaround for this
use-case:

```haskell
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`.