给出以下代码:
newtype HelloMessage = HelloMessage { msg :: String }
deriving (Generic)
instance ToJSON HelloMessage
type API2 = "hello"
:> QueryParam "age" Int
:> Get '[JSON] HelloMessage
appAPI2 :: Proxy API2
appAPI2 = Proxy
myHandler :: Server API2
myHandler = helloHandler
where
helloHandler :: Maybe Int -> Handler HelloMessage
helloHandler mAge =
let
sAge = case mAge of
Nothing -> "0"
Just ag -> show ag
in
return . HelloMessage $ sAge
app2 :: Application
app2 = serve appAPI2 myHandler
main :: IO ()
main = run 8080 app2
我可以访问返回/hello
的{{1}}或返回{ "msg" : 0}
的{{1}}。但是如果我将年龄设置为非整数可解析的,例如/hello?age=20
将url设为{ "msg" : 20}
并对其进行访问,它返回一条有关解析"foobar"
上的错误的错误消息。
这与/hello?age=foobar
的行为不同,如果我给予相同的处理,它将只返回http400。
我的代码有什么问题?
编辑:进一步研究后,解析错误确实返回http 400。现在,我要更改问题。如何返回自定义错误消息,如果 那会发生吗?
答案 0 :(得分:3)
QueryParam
的默认行为是这样的:如果无法解码,则会出错,但是如果未指定,则返回Nothing。
从仆人0.13开始,您可以覆盖它。
如果您查看the definition of QueryParam
,您会发现它实际上只是更一般的QueryParam'
类型的一种特例:
type QueryParam = QueryParam' '[Optional, Strict]
QueryParam'
采用了我们所说的“修饰符”,它影响两件事:
Maybe a
,如果没有,您将直接获得一个a
,但是如果没有给出任何值,它将出错。这是Required
对Optional
。a
。如果不这样做,那么处理程序会得到一个Either Text a
,然后您可以自由地做任何您想做的事情,以防出现解码错误(这是Left
的{{1}}情况,以及文字错误消息)。这是Either
对Strict
。因此,您可能想要定义类似Lenient
之类的东西,并在适当的时候使用它。
能解决您的问题吗?