Copyright | Dennis Gosnell 2017 |
---|---|
License | BSD3 |
Maintainer | Dennis Gosnell (cdep.illabout@gmail.com) |
Stability | experimental |
Portability | unknown |
Safe Haskell | None |
Language | Haskell2010 |
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.