关于haskell:Servant QueryParams解析错误

Servant QueryParams parse error

给出以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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

我可以访问返回{"msg" : 0}/hello或返回{"msg" : 20}/hello?age=20。但是如果我将年龄设置为非整数可解析的,例如"foobar"使URL为/hello?age=foobar并对其进行访问,它返回有关解析"foobar"上的错误的错误消息。

这与Capture的行为不同,如果我给予相同的处理,它将只返回http400。

我的代码有什么问题?

编辑:经过进一步探索,它确实在解析错误时返回http 400。现在,我要更改问题。如何返回自定义错误消息,如果
那会发生吗?


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

自从仆人0.13起,您可以覆盖它。

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

1
type QueryParam = QueryParam' '[Optional, Strict]

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

  • 是否可以在没有该参数值的情况下生存:如果可以,则处理程序得到Maybe a,如果没有,则直接得到a,但是在没有给出值的情况下出错。这是RequiredOptional
  • 是否希望解码失败是致命的:如果这样做,则解码失败时将为您显示仆人错误,否则处理程序将得到a。如果不这样做,那么处理程序将得到一个Either Text a,然后您可以自由地做任何您想做的事情,以防出现解码错误(这是EitherLeft情况,带有文本错误消息) 。这是StrictLenient

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

能解决您的问题吗?