3

该函数forkFinally要求您针对SomeException. 我需要的是一种重新抛出未处理异常的方法。这是一个示例代码,它无法编译,因为在最后一行e是模棱两可的:

finallyHandler :: Either SomeException () -> IO ()
finallyHandler z = case z of
  Right () -> cleanUp
  Left someE | Just ThreadKilled <- fromException someE -> cleanUp
             | Just e <- fromException someE -> cleanUp >> throwIO e

当然首先想到的是简单地抛出someE,即:

             ...
             | otherwise -> cleanUp >> throwIO someE

SomeException确实它会编译,但是当它们通过这个处理程序时,它会导致所有传入异常的包装。这不可能是对的。如果我在堆栈中有多个这样的处理程序怎么办 - 我会得到一个像SomeException $ SomeException $ RealException.

我错过了什么吗?处理这种情况的正确方法是什么?

4

1 回答 1

2

您是否看到意外行为?如果您实际上没有触发一些不受欢迎的事情,那么我认为您无所顾忌。快速测试表明“正确的事情”已经在做。也就是说,如果你 catch then throw aSomeException你仍然可以捕捉到原来的异常。ErrorCall这是一个用作基础异常的示例:

> catch (catch (throw (SomeException (ErrorCall "hi")))
               (\(e::SomeException) -> throw e)) 
        (\(ErrorCall e) -> putStrLn e)
hi

这是因为定义throw使用toExceptiontoException是身份SomeException

instance Exception SomeException where
    toException se = se
    fromException = Just
于 2013-10-23T18:55:31.310 回答