| Copyright | Dennis Gosnell 2017 |
|---|---|
| License | BSD3 |
| Maintainer | Dennis Gosnell (cdep.illabout@gmail.com) |
| Stability | experimental |
| Portability | unknown |
| Safe Haskell | None |
| Language | Haskell2010 |
Servant.Checked.Exceptions
Description
This module gives you the ability to specify which errors are thrown by a
Servant api. This is done with the Throws data type. Here is an example of
creating an api that uses Throws:
type Api =
"author" :>
Capture "author-id" AuthorId :>
Throws CouldNotConnectToDbError :>
Throws AuthorNotFoundError :>
Get '[JSON] Author
This api will return an Author for a given AuthorId. Throws is used
to indicate that this api will potentially return two different errors:
CouldNotConnectToDbError and AuthorNotFoundError.
These two errors might be defined like this:
data CouldNotConnectToDbError = CouldNotConnectToDbError
deriving (Eq, Read, Show)
data AuthorNotFoundError = AuthorNotFoundError
deriving (Eq, Read, Show)
Writing the server handler for this api will look like the following. Notice
how the Envelope type is used:
getAuthorHandler
:: AuthorId
-> Handler (Envelope '[DatabaseError, AuthorNotFoundError] Author)
getAuthorHandler authorId = do
eitherAuthor <- getAuthorFromDb authorId
case eitherAuthor of
Left NoDb -> pure $ toErrEnvelope CouldNotConnectToDbError
Left NoAuthor -> pure $ toErrEnvelope AuthorNotFoundError
Right author -> pure $ toSuccEnvelope author
getAuthorFromDb :: AuthorId -> Handler (Either DbErr Author)
getAuthorFromDb = ...
data DbErr = NoDb | NoAuthor
represents a
response that will contain an Envelope '[DatabaseError, AuthorNotFoundError] AuthorAuthor on success, or contain either a
DatabaseError or a AuthorNotFoundError on error.
Under the hood, Envelope is using an extensible sum-type (OpenUnion) to
represent possible errors. Working with an api that returns two possible
errors is just as easy as working with an api that returns three possible
errors.
Clients will also use the Envelope type:
getAuthor
:: AuthorId
-> ClientM (Envelope '[DatabaseError, AuthorNotFoundError] Author)
getAuthor = client (Proxy :: Proxy Api)
It is easy to do case analysis (similar to pattern matching) on the Envelope
type with the catchesEnvelope function.
Checkout the example in the repository on Github. It includes a fleshed-out example of an api, server, client, and documentation. The README.md shows how to compile and run the examples.