2020-07-30 18:05:46 +02:00
|
|
|
{-# LANGUAGE DataKinds #-}
|
|
|
|
{-# LANGUAGE PolyKinds #-}
|
|
|
|
{-# LANGUAGE RankNTypes #-}
|
2020-06-14 11:15:30 +02:00
|
|
|
{-# LANGUAGE TypeOperators #-}
|
|
|
|
|
|
|
|
module Servant.Server.Internal.ErrorFormatter
|
2020-07-30 18:05:46 +02:00
|
|
|
( ErrorFormatters(..)
|
|
|
|
, ErrorFormatter
|
|
|
|
, NotFoundErrorFormatter
|
|
|
|
|
|
|
|
, DefaultErrorFormatters
|
|
|
|
, defaultErrorFormatters
|
|
|
|
|
|
|
|
, MkContextWithErrorFormatter
|
|
|
|
, mkContextWithErrorFormatter
|
|
|
|
) where
|
2020-06-14 11:15:30 +02:00
|
|
|
|
|
|
|
import Data.String.Conversions
|
|
|
|
(cs)
|
|
|
|
import Data.Typeable
|
|
|
|
import Network.Wai.Internal
|
|
|
|
(Request)
|
|
|
|
|
|
|
|
import Servant.API
|
|
|
|
(Capture, ReqBody)
|
|
|
|
import Servant.Server.Internal.Context
|
|
|
|
import Servant.Server.Internal.ServerError
|
|
|
|
|
|
|
|
-- | 'Context' that contains default error formatters.
|
|
|
|
type DefaultErrorFormatters = '[ErrorFormatters]
|
|
|
|
|
|
|
|
-- | A collection of error formatters for different situations.
|
|
|
|
--
|
|
|
|
-- If you need to override one of them, use 'defaultErrorFormatters' with record update syntax.
|
|
|
|
data ErrorFormatters = ErrorFormatters
|
|
|
|
{ -- | Format error from parsing the request body.
|
|
|
|
bodyParserErrorFormatter :: ErrorFormatter
|
|
|
|
-- | Format error from parsing url parts or query parameters.
|
|
|
|
, urlParseErrorFormatter :: ErrorFormatter
|
|
|
|
-- | Format error from parsing request headers.
|
|
|
|
, headerParseErrorFormatter :: ErrorFormatter
|
|
|
|
-- | Format error for not found URLs.
|
|
|
|
, notFoundErrorFormatter :: NotFoundErrorFormatter
|
|
|
|
}
|
|
|
|
|
|
|
|
-- | Default formatters will just return HTTP 400 status code with error
|
|
|
|
-- message as response body.
|
|
|
|
defaultErrorFormatters :: ErrorFormatters
|
|
|
|
defaultErrorFormatters = ErrorFormatters
|
|
|
|
{ bodyParserErrorFormatter = err400Formatter
|
|
|
|
, urlParseErrorFormatter = err400Formatter
|
|
|
|
, headerParseErrorFormatter = err400Formatter
|
|
|
|
, notFoundErrorFormatter = const err404
|
|
|
|
}
|
|
|
|
|
|
|
|
-- | A custom formatter for errors produced by parsing combinators like
|
|
|
|
-- 'ReqBody' or 'Capture'.
|
|
|
|
--
|
|
|
|
-- A 'TypeRep' argument described the concrete combinator that raised
|
|
|
|
-- the error, allowing formatter to customize the message for different
|
|
|
|
-- combinators.
|
|
|
|
--
|
|
|
|
-- A full 'Request' is also passed so that the formatter can react to @Accept@ header,
|
|
|
|
-- for example.
|
|
|
|
type ErrorFormatter = TypeRep -> Request -> String -> ServerError
|
|
|
|
|
|
|
|
-- | This formatter does not get neither 'TypeRep' nor error message.
|
|
|
|
type NotFoundErrorFormatter = Request -> ServerError
|
|
|
|
|
|
|
|
type MkContextWithErrorFormatter (ctx :: [*]) = ctx .++ DefaultErrorFormatters
|
|
|
|
|
|
|
|
mkContextWithErrorFormatter :: forall (ctx :: [*]). Context ctx -> Context (MkContextWithErrorFormatter ctx)
|
|
|
|
mkContextWithErrorFormatter ctx = ctx .++ (defaultErrorFormatters :. EmptyContext)
|
|
|
|
|
|
|
|
-- Internal
|
|
|
|
|
|
|
|
err400Formatter :: ErrorFormatter
|
|
|
|
err400Formatter _ _ e = err400 { errBody = cs e }
|
|
|
|
|
|
|
|
-- These definitions suppress "unused import" warning.
|
|
|
|
-- The imorts are needed for Haddock to correctly link to them.
|
|
|
|
_RB :: Proxy ReqBody
|
2020-07-30 18:05:46 +02:00
|
|
|
_RB = Proxy
|
2020-06-14 11:15:30 +02:00
|
|
|
_C :: Proxy Capture
|
2020-07-30 18:05:46 +02:00
|
|
|
_C = Proxy
|
2020-06-14 11:15:30 +02:00
|
|
|
_CT :: Proxy Context
|
2020-07-30 18:05:46 +02:00
|
|
|
_CT = Proxy
|