wai-problem-details-0.1.0.0: src/Network/Wai/Middleware/ProblemDetails.hs
-- | Middleware for WAI that implements the problem details RFC specified in
-- https://www.rfc-editor.org/rfc/rfc7807.
--
-- Example:
--
-- > {-# LANGUAGE OverloadedStrings #-}
-- >
-- > module Main where
-- >
-- > import Network.Wai.Handler.Warp (run)
-- > import Data.Default
-- > import Network.Wai.Middleware.ProblemDetails
-- >
-- > main :: IO ()
-- > main = run 8080 $ problemDetails $ app
-- > where
-- > app request respond = throwProblemDetails def
--
-- See the project's README and tests for more examples.
--
module Network.Wai.Middleware.ProblemDetails
(
module Network.Wai.Middleware.ProblemDetails.Internal.Types
, module Network.Wai.Middleware.ProblemDetails.Internal.Exception
, module Network.Wai.Middleware.ProblemDetails.Internal.Defaults
, problemDetails
)
where
import Network.Wai.Middleware.ProblemDetails.Internal.Defaults
import Network.Wai.Middleware.ProblemDetails.Internal.Exception
import Network.Wai.Middleware.ProblemDetails.Internal.Types
import Control.Exception (catch)
import Data.Aeson (encode)
import Data.ByteString
import Data.Text.Encoding (encodeUtf8)
import Network.HTTP.Types (mkStatus)
import Network.Wai (Middleware,
Response,
responseLBS)
-- | Middleware that sends a problem+json response when an exception of type
-- 'ProblemDetailsException' is thrown from a WAI application.
problemDetails :: Middleware
problemDetails app = \request respond -> app request respond `catch` (respond . catchProblemDetails)
where
catchProblemDetails :: ProblemDetailsException -> Response
catchProblemDetails (ProblemDetailsException pd) = responseLBS
(uncurry mkStatus $ getStatus pd)
[("Content-Type", "application/problem+json")]
(encode pd)
getStatus :: ProblemDetails -> (Int, ByteString)
getStatus pd = case (status pd, title pd) of
(Just status', Just title') -> (status', encodeUtf8 title')
_ -> (200, "Ok")