用ExceptT捕获SomeException [英] Catch SomeException with ExceptT

查看:143
本文介绍了用ExceptT捕获SomeException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆