Servant QueryParams解析错误

第322章

给出以下代码:

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。现在,我要更改问题。如果发生这种情况,如何返回自定义错误消息?

高山Mestanogullari

的默认行为QueryParam是这样的:如果无法解码,则会出错,但未指定时将返回Nothing。

从0.13开始,您可以覆盖它。

如果查看的定义QueryParam,您会发现它实际上只是更通用QueryParam'类型的一种特殊情况

type QueryParam = QueryParam' '[Optional, Strict]

QueryParam' 采用我们所说的“修饰符”,它影响两件事:

  • 是否可以在没有该参数值的情况下生存:如果可以,则处理程序将获取一个Maybe a,如果不是,则直接获取一个,a但是在未提供任何值时会出错。这是RequiredVS Optional
  • 是否希望解码失败是致命的:如果这样做,则解码失败时将为您显示仆人错误,否则处理程序将收到a如果您不这样做,则处理程序将得到一个,然后您Either Text a可以自由地做任何您想做的事情,以防出现解码错误(Left对于Either带有文本错误消息的,就是这样)。这是StrictVS Lenient

因此,您可能想定义类似的东西,type MyQueryParam name a = QueryParam' '[Optional, Lenient]并在适当的时候使用它。

这样可以解决您的问题吗?

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章