为什么`catch`不能捕获这个异常?

用户名

我有一个Servant应用程序和一个端点,该端点在数据库中创建一条记录,然后尝试在S3位置之间复制文件。如果复制失败,我想回滚事务。我有这个接线员

{-# LANGUAGE TemplateHaskell #-}    

import Control.Monad.Catch
import Control.Monad.Except
import Control.Monad.Logger

(<??)
  :: (MonadError e m, MonadCatch m, MonadLogger m)
  => e
  -> m a
  -> m a
(<??) err a = a `catchAll` (\e -> $(logErrorSH) e >> throwError err)
infixr 0 <??

捕获所有异常,记录异常的性质,然后引发(在我的情况下,因为我的App类型具有的实例MonadError ServantErr)a ServantErr

我的处理程序是这样的:

{-# LANGUAGE ScopedTypeVariables #-}

import           Control.Monad
import           Control.Monad.Catch
import           Control.Monad.IO.Class
import qualified Network.AWS as AWS
import           Servant

import App.Types
import App.Db


copy :: Copy -> App Text
copy (Copy user bucket srcKey tgtKey) = do
  err400 <?? runDb (insertRecord $ User user bucket srcKey tgtKey)

  catch (err500 <?? liftIO $ do
    env <- AWS.newEnv AWS.Discover
    void . AWS.runResourceT . AWS.runAWS env $ copyFiles bucket srcKey tgtKey
    return "OK") (\(e :: ServantErr) -> rollback e user)
  where rollback e u = runDb (deleteRecord u) >> throwError e

为了测试逻辑,我移动了我的AWS凭证文件,期望内部AWS操作将抛出InvalidFileError,然后(<??)将其转换为ServantErr,然后catch将其捕获ServantErr并制定回滚功能。相反,发生的事情是插入成功,InvalidFileError记录了日志,但是回滚从未发生(即,执行后记录仍存在于数据库中)。deleteRecord函数已在其他地方成功使用,因此可以确定它的定义不是问题。

知道是什么原因造成的吗?

danidiaz

如果您的App类型最终是ExceptT,则问题可能是MonadError和的MonadCatch实例ExceptT不匹配:

  • MonadError实例会引发错误的eExceptT e
  • MonadCatch实例在基础monad中捕获异常,而不是ExceptT e错误。

实例定义MonadCatch (ExceptT e m)

-- | Catches exceptions from the base monad.
instance MonadCatch m => MonadCatch (ExceptT e m) where
   catch (ExceptT m) f = ExceptT $ catch m (runExceptT . f)

ServantErr有一个Exception实例,因此可以将两者同时抛出。


编辑:“ exceptions”类MonadMask提供了onError功能,即使对于ExceptT它来说也表现得很好:在ExceptT e异常常规异常的情况下,它都运行清除操作

仅在主操作中引发错误时才运行操作。与onException不同,这适用于各种错误,而不仅仅是异常。例如,如果f是用Left终止的ExceptT计算,则onError fg计算将执行g,而onException fg则不会。

这比catch处理回滚更好

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我不能捕获OOM异常?

来自分类Dev

为什么不能在通用catch子句中捕获自定义异常

来自分类Dev

为什么C ++ try / catch不能捕获“纯虚拟调用”异常?

来自分类Dev

为什么不能通过try / catch SqlException捕获SqlException类型的异常?

来自分类Dev

为什么这个基本的 Try-Catch 无法捕获

来自分类Dev

为什么我的诺言的catch子句没有捕获异常?

来自分类Dev

为什么try catch块没有捕获promise异常?

来自分类Dev

为什么我不能正确捕获此异常?

来自分类Dev

为什么我不能多次捕获该异常?

来自分类Dev

为什么不能尝试捕获某些异常的工作?

来自分类Dev

使用try:捕获异常时,为什么不能返回?

来自分类Dev

为什么派生类异常可以被基类catch子句捕获。

来自分类Dev

在函数中捕获异常,在 try-catch 中调用。不起作用,为什么?

来自分类Dev

为什么我的`main()`不能捕获junit测试中`timer`中抛出的异常?

来自分类Dev

当我的lua代码引发错误时,为什么不能捕获luabind :: error异常?

来自分类Java

为什么您可以抛出未发生的异常但不能捕获它

来自分类Java

为什么不捕获异常的代码允许捕获检查异常?

来自分类Dev

为什么这个索引签名不能是可选的?

来自分类Dev

为什么我不能投射这个界面?

来自分类Dev

为什么这个div不能居中?

来自分类Dev

为什么我不能选择这个?-硒

来自分类Dev

为什么 XPath 不能定位这个元素?

来自分类Dev

为什么这个查询不能正常工作?

来自分类Dev

为什么这个 for 循环不能并行工作?

来自分类Dev

为什么这个Jekyll插件抛出异常?

来自分类Dev

为什么我从 AutoclearedValue 得到这个异常?

来自分类Dev

为什么Catch没有捕获错误?

来自分类Dev

为什么这个TypeScript常量不能满足这个接口?

来自分类Dev

为什么这个变量不能改变这个值?

Related 相关文章

  1. 1

    为什么我不能捕获OOM异常?

  2. 2

    为什么不能在通用catch子句中捕获自定义异常

  3. 3

    为什么C ++ try / catch不能捕获“纯虚拟调用”异常?

  4. 4

    为什么不能通过try / catch SqlException捕获SqlException类型的异常?

  5. 5

    为什么这个基本的 Try-Catch 无法捕获

  6. 6

    为什么我的诺言的catch子句没有捕获异常?

  7. 7

    为什么try catch块没有捕获promise异常?

  8. 8

    为什么我不能正确捕获此异常?

  9. 9

    为什么我不能多次捕获该异常?

  10. 10

    为什么不能尝试捕获某些异常的工作?

  11. 11

    使用try:捕获异常时,为什么不能返回?

  12. 12

    为什么派生类异常可以被基类catch子句捕获。

  13. 13

    在函数中捕获异常,在 try-catch 中调用。不起作用,为什么?

  14. 14

    为什么我的`main()`不能捕获junit测试中`timer`中抛出的异常?

  15. 15

    当我的lua代码引发错误时,为什么不能捕获luabind :: error异常?

  16. 16

    为什么您可以抛出未发生的异常但不能捕获它

  17. 17

    为什么不捕获异常的代码允许捕获检查异常?

  18. 18

    为什么这个索引签名不能是可选的?

  19. 19

    为什么我不能投射这个界面?

  20. 20

    为什么这个div不能居中?

  21. 21

    为什么我不能选择这个?-硒

  22. 22

    为什么 XPath 不能定位这个元素?

  23. 23

    为什么这个查询不能正常工作?

  24. 24

    为什么这个 for 循环不能并行工作?

  25. 25

    为什么这个Jekyll插件抛出异常?

  26. 26

    为什么我从 AutoclearedValue 得到这个异常?

  27. 27

    为什么Catch没有捕获错误?

  28. 28

    为什么这个TypeScript常量不能满足这个接口?

  29. 29

    为什么这个变量不能改变这个值?

热门标签

归档