| CARVIEW |
servant-typed-error: Typed error wrapper for Servant
Downloads
- servant-typed-error-0.1.2.0.tar.gz [browse] (Cabal source package)
- Package description (as included in the package)
Maintainer's Corner
For package maintainers and hackage trustees
Candidates
- No Candidates
| Versions [RSS] | 0.1.2.0 |
|---|---|
| Change log | ChangeLog.md |
| Dependencies | aeson (>=2.1.1 && <2.2), base (>=4.13 && <4.18), mtl (>=2.2.2 && <2.3), servant (>=0.19 && <0.20), servant-client (>=0.19 && <0.20), servant-server (>=0.19.1 && <0.20), sop-core (>=0.5.0.2 && <0.6) [details] |
| License | MIT |
| Copyright | 2021 Plow Technologies LLC |
| Author | Sam Balco |
| Maintainer | info@plowtech.net |
| Uploaded | by sidk at 2022-11-28T05:24:39Z |
| Category | Web, Servant |
| Home page | https://github.com/plow-technologies/servant-typed-error.git#readme |
| Bug tracker | https://github.com/plow-technologies/servant-typed-error.git/issues |
| Source repo | head: git clone https://github.com/plow-technologies/servant-typed-error.git |
| Distributions | |
| Reverse Dependencies | 1 direct, 1 indirect [details] |
| Downloads | 167 total (4 in the last 30 days) |
| Rating | (no votes yet) [estimated by Bayesian average] |
| Your Rating |
|
| Status | Docs available [build log] Last success reported on 2022-11-28 [all 1 reports] |
Readme for servant-typed-error-0.1.2.0
[back to package description]servant-typed-error
This is a small wrapper for the exception approach detailed here: https://docs.servant.dev/en/stable/cookbook/uverb/UVerb.html?highlight=exceptions
This library allows sending and receiving Typed errors via servant. For example, we can define the following API:
data APIError = Whoops | Bad Int
deriving (Generic, ToJSON, FromJSON)
type API =
"foo" :> Capture "number" Int :> GetTypedError '[JSON] Bool APIError
:<|> "whoops" :> GetTypedError '[JSON] Int APIError
Here we use GetTypedError instead of the usual Get to indicate the API can return an ApiError, which must have a ToJSON/FromJSON instance.
There are two ways of writing a server for this API. We can either use the TypedHandler monad, which has throwTypedError and throwServantError functions allowing us to either throw our custom typed error or a generic ServantError. Another approach using a generic mtl style definition of a monad with a MonadError e m constraint; we can then use liftTypedError to lift it into servant's Handler monad:
alwaysWhoops :: MonadError APIError m => m Int
alwaysWhoops = throwError Whoops
server :: Server API
server =
( \i ->
runTypedHandler $ case i of
42 -> throwTypedError $ Bad i
-1 -> throwServantError err500
x -> pure $ x `mod` 2 == 0
)
:<|> liftTypedError alwaysWhoops
Finally, we can recover the errors on the client side via a special TypedClientM e a monad. We use the typedClient to convert the servant-client API to use our TypedClientM:
foo :: Int -> TypedClientM APIError Bool
whoops :: TypedClientM APIError Int
foo :<|> whoops = typedClient $ client $ Proxy @API
Then, using runTypedClientM we can obtain an Either (Either ClientError APIError) a and pattern match on both the generic servant-client error or the user defined APIError.
Differences with other servant typed error/exception libs
-
servant-checked-exceptions This library wraps the response in a custom type, so it would be a bit awkward to use with the frontend. The approach here sends the same 200 response as vanilla servant would
-
servant-exceptions Not investigated much since it's missing the client implementation