用ExceptT捕获SomeException [英] Catch SomeException with ExceptT
问题描述
我正在尝试使用 ExceptT
monad变换器来捕获函数抛出的任何异常,如下所示:
I'm trying to use the ExceptT
monad transformer to catch any exception thrown by a function, like so:
import Control.Exception
import Control.Monad.Trans.Except
badFunction :: ExceptT SomeException IO ()
badFunction = throw DivideByZero
main :: IO ()
main = do
r <- runExceptT badFunction
case r of Left _ -> putStrLn "caught error"
Right _ -> putStrLn "nope, didn't catch no error"
...但异常愉快地飞过。我做错了什么?
... but the exception happily flies by. What am I doing wrong?
修改:澄清,目的是抓住任何异常函数,无论抛出异常。如果它有任何差异,那么真正的功能调用是在一个相当深的单体变压器堆栈的底部。我不介意丢失的东西,如抛出的字符串(坏的程序员!)。
Edit: to clarify, the aim is to catch any exception thrown by a function, regardless of how the exception was thrown. If it makes any difference, the real function call is at the bottom of a fairly deep monad transformer stack. I don't mind missing things like thrown strings (bad programmer!).
推荐答案
首先,您捕获运行时异常。可以使用 monad-control
(和 lifting-base
)或异常
。迈克尔·斯诺伊曼(Michael Snoyman)有一篇很好的文章比较了这两个:例外和monad变压器
First, you catch your runtime exception. It can be done by using either monad-control
(and lifted-base
) or exceptions
. Michael Snoyman has a nice article comparing the two: Exceptions and monad transformers
其次,您将嵌入的异常嵌入到 ExceptT
中。
Second, you embed the caught exception in ExceptT
.
以下是完整的工作代码:
Here's the complete working code:
import Control.Exception.Lifted
import Control.Monad.Trans.Except
badFunction :: ExceptT SomeException IO ()
badFunction = throw DivideByZero
intercept
:: ExceptT SomeException IO a
-> ExceptT SomeException IO a
intercept a = do
r <- try a
case r of
Right x -> return x
Left e -> throwE e
main :: IO ()
main = do
r <- runExceptT $ intercept badFunction
case r of Left _ -> putStrLn "caught error"
Right _ -> putStrLn "nope, didn't catch no error"
更紧凑(但可能有些不那么明显)定义 intercept
是
A more compact (but perhaps somewhat less obvious) definition of intercept
is
intercept
:: ExceptT SomeException IO a
-> ExceptT SomeException IO a
intercept = handle throwE
这篇关于用ExceptT捕获SomeException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!