给出以下代码:
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
哪个返回{ "msg" : 0}
或/hello?age=20
哪个返回{ "msg" : 20}
。但是,如果我将年龄设置为非整数可解析的(例如"foobar"
,使url为/hello?age=foobar
并可以访问它),它将返回有关解析错误on的错误消息"foobar"
。
Capture
如果我给予相同的处理,它将返回一个http 400,这在行为上有所不同。
我的代码有什么问题?
编辑:进一步探索后,它的解析错误确实返回http 400。现在,我要更改问题。如果发生这种情况,如何返回自定义错误消息?
的默认行为QueryParam
是这样的:如果无法解码,则会出错,但未指定时将返回Nothing。
从0.13开始,您可以覆盖它。
如果查看的定义QueryParam
,您会发现它实际上只是更通用QueryParam'
类型的一种特殊情况:
type QueryParam = QueryParam' '[Optional, Strict]
QueryParam'
采用我们所说的“修饰符”,它影响两件事:
Maybe a
,如果不是,则直接获取一个,a
但是在未提供任何值时会出错。这是Required
VS Optional
。a
。如果您不这样做,则处理程序将得到一个,然后您Either Text a
可以自由地做任何您想做的事情,以防出现解码错误(Left
对于Either
带有文本错误消息的,就是这样)。这是Strict
VS Lenient
。因此,您可能想定义类似的东西,type MyQueryParam name a = QueryParam' '[Optional, Lenient]
并在适当的时候使用它。
这样可以解决您的问题吗?
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句