【问题标题】:Haskell Servant Custom JSON parsing errorsHaskell Servant 自定义 JSON 解析错误
【发布时间】:2018-05-31 01:46:24
【问题描述】:

给定以下Servant服务器:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}

module ServantSample (main) where

import Data.Aeson
import Data.Aeson.TH
import Network.Wai
import Network.Wai.Handler.Warp
import Servant

data Spec = Spec
  { schema :: Object
  } deriving (Eq, Show)
$(deriveJSON defaultOptions ''Spec)

type Api = ReqBody '[JSON] Spec :> Post '[JSON] NoContent

server :: Server Api
server = postDoc

postDoc :: Spec -> Handler NoContent
postDoc _ = return NoContent

api :: Proxy Api
api = Proxy

app :: Application
app = serve api server

main :: IO ()
main = run 8080 app

...以及以下 curl 到上述服务器的运行实例:

curl localhost:8080 -H 'Content-Type: application/json' --data '{"schema": "I am not an object but I should be!"}'

我回来了:

Error in $.schema: expected HashMap ~Text v, encountered String

有没有办法拦截 Aeson 错误并将其替换为不会将实现细节泄露给客户端的东西?据我所知,这一切都发生在 Servant 机器的幕后,我找不到任何关于如何连接它的文档。

例如,我想返回如下内容:

Expected a JSON Object under the key "schema", but got the String "I am not an object but I should be!"

谢谢!

【问题讨论】:

  • 我相信this 可能是相关的。

标签: json haskell aeson servant


【解决方案1】:

手动编写 FromJSON 实例可以解决至少一半的问题。

instance FromJSON Spec where
  parseJSON (Object o) = do
    schema <- o .: "schema"
    case schema of
      (Object s) -> pure $ Spec s
      (String s) -> fail $ "Expected a JSON Object under the key \"schema\", but got the String \"" ++ unpack s ++ "\"\n"
      _          -> fail $ "Expected a JSON Object under the key \"schema\", but got the other type"
  parseJSON wat = typeMismatch "Spec" wat

然后你的 curl 命令返回:

Error in $: Expected a JSON Object under the key "schema", but got the String "I am not an object but I should be!"

您显然可以检查来自 Aeson 的不同 Value 类型构造函数并将其分解为单独的函数。

通过查看Data.Aeson.Types.typeMismatch的实现得到代码

【讨论】:

  • 错误信息中的“Error in $”部分来自Aeson的Parser。不知道更换会有多困难。
  • 哦,呵呵——回想起来,很明显。我最终将您的解决方案与here 的中间件解决方案结合使用,以删除“$ 中的错误:”并将错误嵌入到 JSON 对象中。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多