@@ -15,6 +15,8 @@ import qualified Data.ByteString.Lazy.Char8 as BCL
15import Data.Monoid
15import Data.Monoid
17import Data.Proxy
17import Data.Proxy
18+import Data.String.Conversions
18import Network.HTTP.Types
20import Network.HTTP.Types
19 (hAccept, hAuthorization, hContentType, methodGet, methodPost,
21 (hAccept, hAuthorization, hContentType, methodGet, methodPost,
20 methodPut)
22 methodPut)
@@ -31,6 +33,7 @@ spec = describe "HTTP Errors" $ do
31 prioErrorsSpec
33 prioErrorsSpec
32 errorRetrySpec
34 errorRetrySpec
33 errorChoiceSpec
35 errorChoiceSpec
35-- * Auth machinery (reused throughout)
38-- * Auth machinery (reused throughout)
@@ -293,6 +296,61 @@ errorChoiceSpec = describe "Multiple handlers return errors"
293 `shouldRespondWith` 415
296 `shouldRespondWith` 415
300+------------------------------------------------------------------------------
301+-- * Custom errors {{{
303+customFormatter :: ErrorFormatter
304+customFormatter _ _ err = err400 { errBody = "CUSTOM! " <> cs err }
306+customFormatters :: ErrorFormatters
307+customFormatters = defaultErrorFormatters
308+ { bodyParserErrorFormatter = customFormatter
309+ , urlParseErrorFormatter = customFormatter
310+ , notFoundErrorFormatter = const $ err404 { errBody = "CUSTOM! Not Found" }
313+type CustomFormatterAPI
314+ = "query" :> QueryParam' '[Required, Strict] "param" Int :> Get '[PlainText] String
315+ :<|> "capture" :> Capture "cap" Bool :> Get '[PlainText] String
316+ :<|> "body" :> ReqBody '[JSON] Int :> Post '[PlainText] String
318+customFormatterAPI :: Proxy CustomFormatterAPI
319+customFormatterAPI = Proxy
321+customFormatterServer :: Server CustomFormatterAPI
322+customFormatterServer = (\_ -> return "query")
323+ :<|> (\_ -> return "capture")
324+ :<|> (\_ -> return "body")
326+customFormattersSpec :: Spec
327+customFormattersSpec = describe "Custom errors from combinators"
328+ $ with (return $ serveWithContext customFormatterAPI (customFormatters :. EmptyContext) customFormatterServer) $ do
330+ let startsWithCustom = ResponseMatcher
333+ , matchBody = MatchBody $ \_ body -> if "CUSTOM!" `BCL.isPrefixOf` body
335+ else Just $ show body <> " does not start with \"CUSTOM!\""
338+ it "formats query parse error" $ do
339+ request methodGet "query?param=false" [] ""
340+ `shouldRespondWith` startsWithCustom
342+ it "formats query parse error with missing param" $ do
343+ request methodGet "query" [] ""
344+ `shouldRespondWith` startsWithCustom
346+ it "formats capture parse error" $ do
347+ request methodGet "capture/42" [] ""
348+ `shouldRespondWith` startsWithCustom
350+ it "formats body parse error" $ do
351+ request methodPost "body" [(hContentType, "application/json")] "foo"
352+ `shouldRespondWith` startsWithCustom
297------------------------------------------------------------------------------
355------------------------------------------------------------------------------
298-- * Instances {{{
356-- * Instances {{{