servant-errors alternatives and similar packages
Based on the "network" category.
Alternatively, view servant-errors alternatives based on common mentions on social networks and blogs.
-
compendium-client
Mu (μ) is a purely functional framework for building micro services. -
dmcc
Haskell bindings for AVAYA DMCC API and WebSockets server for AVAYA -
nakadi-client
Haskell Client Library for the Nakadi Event Broker -
resolv
Domain Name Service (DNS) lookup via the libresolv standard library routines -
network-address
IP data structures and textual representation -
network-data
Network data structures in Haskell (IP, UDP, TCP headers, etc) -
windns
Domain Name Service (DNS) lookup via the Windows dnsapi standard library -
network-uri-json
FromJSON and ToJSON Instances for Network.URI -
hatexmpp3
XMPP client with synthetic filesystem (9P) and (optional) graphical (GTK3) interfaces -
LDAPv3
Lightweight Directory Access Protocol V3 (LDAPv3) RFC4511 implementation -
hsendxmpp
sendxmpp clone and drop-in replacement, sending XMPP messages via CLI -
transient-universe-tls
Secure communications for transient-universe -
network-voicetext
VoiceText Web API Haskell wrapper library -
oauth2-jwt-bearer
OAuth2 jwt-bearer client flow as per rfc7523. -
iwlib
A binding to the iw library for getting info about the current WiFi connection. -
attoparsec-uri
A compositional URI parser / printer for attoparsec -
network-uri-lenses
lenses for http://hackage.haskell.org/package/network-uri -
network-simple-wss
Simple Haskell interface to TLS secured WebSockets -
google-oauth2-easy
📛 Easy Google Authentication integration - Authorization Code & Refresh Token
Access the most powerful time series database as a service
Do you think we are missing an alternative of servant-errors or a related project?
README
servant-errors
Intro
This package implements a wai-middleware targeting servant-server applications with a goal of make it easier to generate custom server error responses.
Checkout accompanying blogpost for more details.
Motivation
By default, when your servant server application experiences an internal exception during endpoint route resolution, e.g. request body decode errors, the server response is just plain text with a status code in the HTTP headers.
At the same time, if you don't write custom code to customise error responses for errors thrown within servant route handlers; the default response is plain text with an HTTP content-type when provided within ServerError
.
With servant-errors
library, you get a single interface to structure and encode your error responses in one place as JSON
error response or any other preferred form.
```haskell ignore -- | A typical servant application is usually of this form
main :: IO () main = run 8001 (serve proxyApi handlers)
-- | With 'errorMw' from servant-errors library as an error processing middleware main :: IO () main = run 8001 $ errorMw @JSON @'["error", "status"] -- ^ Structures error response as JSON objects -- with 'error' and 'status' strings as error object field keys -- note they can be changed to any other preferred strings. $ serve proxyApi handlers
-- | The implementation above can also be written as below -- if you want to output JSON error responses with 'error' -- and 'status' as the JSON Object keys main :: IO () main = run 8001 $ errorMwDefJson -- ^ Default implementation of structuring error responses as JSON -- with no customisation option for JSON error object field keys $ serve proxyApi handlers
## Complete Usage Example
```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Main where
import Data.Aeson (FromJSON, ToJSON)
import Data.Proxy (Proxy(..))
import Data.Text (Text)
import GHC.Generics (Generic)
import Network.Wai (Application)
import Network.Wai.Handler.Warp (run)
import Network.Wai.Middleware.Servant.Errors (errorMw, HasErrorBody(..))
import Servant (ReqBody, (:>), Post, JSON, Accept(..), serve)
-- | A greet message data type for use as Request Body
newtype Greet = Greet { msg :: Text }
deriving (Generic, Show, FromJSON, ToJSON)
-- servant application
main' :: IO ()
main' = run 8001
$ errorMw @JSON @'["error", "status"]
-- ^ @JSON specifies content type encoding of errors
-- @["error", "status"] specifies error and code text label in resulting JSON error response
-- when an empty type level list parameter for 'errorMw' is specified
-- the 'HasErrorBody' instance defaults it to '@["error", "status"]' for JSON and PlainText instances
-- hence; errorMw @JSON @'[] == @JSON @["error", "status"]
$ serve api handler
where
handler = return . id
api = Proxy @(ReqBody '[JSON] Greet :> Post '[JSON] Greet)
-- | Example Below shows the derivation of an alternative 'HasErrorBody' instance
-- for JSON error responses if you want to implement more customisation
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
-- | We need a newtype like data type to avoid orphan instances, 'Ctyp' satisfy's that
-- Also note that 'HasErrorBody' instance requires an Accept instance for a content-type
data Ctyp a
{-
if you are using GHC 8.6 and above you can make use of deriving Via
for creating the Accept Instance
>> data Ctyp a
>> deriving Accept via JSON
-}
instance Accept (Ctyp JSON) where
contentType _ = contentType (Proxy @JSON)
instance HasErrorBody (Ctyp JSON) '[] where
encodeError = undefined -- write your custom implementation
-- | Example Middleware with a different 'HasErrorBody' instance for JSON
errorMwJson :: Application -> Application
errorMwJson = errorMw @(Ctyp JSON) @'[]
If a user submits a wrong request body during an HTTP request the HTTP error response is of the formats below;
Error response body while using this package's error Middleware .
{
"status": 400,
"error": "Error in $: key \"msg\" not present"
}
# The response is JSON encoded and contains an HTTP content-type header plus a status code.
Default error response without middleware;
"Error in $: key \"msg\" not present"
# The response is plain text, contains an HTTP status code but lacks an HTTP content-type header.
Documentation
This README is tested by markdown-unlit
to make sure the code builds. To keep that happy, we do need a main
in this file, so ignore the following :)
main :: IO ()
main = pure ()
*Note that all licence references and agreements mentioned in the servant-errors README section above
are relevant to that project's source code only.