首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在servant中捕获IO异常

在servant中捕获IO异常
EN

Stack Overflow用户
提问于 2019-02-19 17:45:28
回答 1查看 213关注 0票数 0

我使用servant实现一个简单的JSON api,它允许您创建用户,其名称必须是惟一的。这是由SQLite中的唯一约束强制执行的。我有一个函数DB.saveUser :: UserReq -> IO Int,它(毫不奇怪)将用户保存到SQLite并返回生成的id。如果该名称已经被采用,它将抛出一个SQLError ErrorConstraint _ _。如果发生这种情况,我希望返回HTTP响应代码409。所以我的问题是,有什么方法可以在Handler Monad中捕获SQLError吗?如果不是,那么实现我想要的最干净的方式是什么呢?我想过让DB.saveUser返回一个Maybe Int,但不知何故,我认为肯定有更好的解决方案。

代码语言:javascript
复制
createUser :: UserReq -> Handler (Headers '[Header "Location" Text] NoContent)
createUser ur = do id <- liftIO (DB.saveUser ur)
                   return . addHeader (T.pack ("/user/" ++ show id)) $ NoContent

saveUser (UR.UserReq name) = withConnection database $ \conn ->
  do executeNamed conn "INSERT INTO users (name) VALUES (:name)" [":name" := name]
     fromIntegral <$> lastInsertRowId conn
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-19 19:12:42

Servant's Handler是一个新类型的包装器:

代码语言:javascript
复制
newtype Handler a = Handler { runHandler' :: ExceptT ServantErr IO a }

里面有一个ExceptT ServantErr,其中ServantErr是:

代码语言:javascript
复制
data ServantErr = ServantErr { errHTTPCode     :: Int
                             , errReasonPhrase :: String
                             , errBody         :: LBS.ByteString
                             , errHeaders      :: [HTTP.Header]
                             } deriving (Show, Eq, Read, Typeable)

因此,您可以在trybracket中运行DB操作,并将DB异常映射到ServantErr,以获得您想要的HTTP响应代码。

如何在捕获数据库异常后抛出ServantErrhttps://haskell-servant.readthedocs.io/en/stable/tutorial/Server.html#failing-through-servanterr

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54763143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档