我刚刚开始学习 Haskell,并且一直坚持如何在 Scotty 中处理异常。
我有下面的基本功能。它获取 JSON POST,将其转换为 Haskell 数据记录,从配置读取器获取 postgres 连接池,然后将记录插入数据库。
create :: ActionT Text ConfigM ()
create = do
a :: Affiliate <- jsonData
pool <- lift $ asks pool
_ <- liftIO $ catchViolation catcher $ withResource pool $ \conn ->
PgSQL.execute conn "INSERT INTO affiliate (id, network, name, status) VALUES (?, ?, ?, ?)"
(slug a, network a, name a, status a)
let s = fromStrict $ unSlug $ slug a
text $ "Created: " `T.append` s
where
catcher e (UniqueViolation "mykey") = throw e --text "Error"
catcher e _ = throw e
此函数编译正常,但是当我将 UniqueViolation 更改为返回文本时,它无法编译。
catcher e (UniqueViolation "mykey") = text "Error"
给出的编译错误是:
Couldn't match type ‘ActionT e0 m0 ()’ with ‘IO Int64’
Expected type: PgSQL.SqlError -> ConstraintViolation -> IO Int64
Actual type: PgSQL.SqlError
-> ConstraintViolation -> ActionT e0 m0 ()
In the first argument of ‘catchViolation’, namely ‘catcher’
In the expression: catchViolation catcher
catchViolation来自Database.PostgreSQL.Simple.Errors并具有以下签名:
catchViolation :: (SqlError -> ConstraintViolation -> IO a) -> IO a -> IO a
我知道问题的一部分是它从 PgSQL.execute 获取 IO Int64,但从捕手获取 ActionT 但不确定如何解决类型或更惯用的方法。