【发布时间】:2019-06-21 19:26:05
【问题描述】:
我想在仆人处理程序 monad 中处理数据库异常。
我尝试使用 Control.Exception 包中的 try 函数来与 Left exception -> throwError err422 { errBody = ... } 进行大小写匹配。
我正在使用postgresql-typed 与 PostgreSQL 数据库进行交互。我想捕获一个PGError 异常。
relevant code 进行以下修改:
accountHandler :: CreateAccountPayload -> Handler Account
accountHandler payload =
let errors = validateCreateAccountPayload payload in
if hasErrors errors then
throwError err422 { errBody = JSON.encode errors }
else
do
result <- try (liftIO (insertAccount payload))
case result of
Right account -> return account
Left exception -> throwError err422 { errBody = JSON.encode [ValidationError (Text.pack "email") (Text.pack "is already taken")] }
我希望能够从数据库调用中捕获结果并进行大小写匹配。案例应该是例外或价值。我目前收到以下编译错误:
src/Main.hs:64:17: error:
• Couldn't match type ‘IO’ with ‘Handler’
Expected type: Handler (Either e0 Account)
Actual type: IO (Either e0 Account)
• In a stmt of a 'do' block:
result <- try (liftIO (insertAccount payload))
In the expression:
do result <- try (liftIO (insertAccount payload))
case result of
Right account -> return account
Left exception -> throwError err422 {errBody = encode ...}
In the expression:
if hasErrors errors then
throwError err422 {errBody = encode errors}
else
do result <- try (liftIO (insertAccount payload))
case result of
Right account -> return account
Left exception -> throwError ...
|
64 | result <- try (liftIO (insertAccount payload))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
【问题讨论】:
-
我不确定,但我认为
liftIO将您的IO Account结果提升到Handlermonad。如果是这样,也许try应该先走,liftIO第二:result <- liftIO (try (insertAccount payload))。 -
@MarkSeemann 将案例中的模式匹配更新为
Left (PGError e) ->就成功了。谢谢!如果您发布该答案,我会接受。