Haskell Servant Custom JSON 解析错误
Haskell Servant Custom JSON parsing errors
给定以下 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 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 机器的幕后,我找不到任何关于如何连接它的文档。
例如,我喜欢 return 像这样的东西:
Expected a JSON Object under the key "schema", but got the String "I am not an object but I should be!"
谢谢!
手动编写 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 命令然后 returns:
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
类型构造函数,并将其分解为一个单独的函数。
的实现获得代码
给定以下 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 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 机器的幕后,我找不到任何关于如何连接它的文档。
例如,我喜欢 return 像这样的东西:
Expected a JSON Object under the key "schema", but got the String "I am not an object but I should be!"
谢谢!
手动编写 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 命令然后 returns:
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
类型构造函数,并将其分解为一个单独的函数。