我试图了解如何捕获管道中引发的错误。我相信通过在管道上应用catchC
,我可以产生一个新的管道,在发生故障时会重新运行。
在下面的示例中,我们有一个源,根据布尔值,将抛出自定义虚拟异常。最初,该布尔值会导致抛出该异常,但catchC
内的处理程序会产生一个新的管道,该管道应该表现出相反的行为(从1到10产生数字)
{-# LANGUAGE DeriveDataTypeable #-}
module Main where
import Data.Conduit
import qualified Data.Conduit.List as CL
import Control.Monad.IO.Class
import Control.Exception
import Data.Typeable
data MyException = MyException String
deriving (Show, Typeable)
instance Exception MyException where
listAsStream :: Bool -> Source IO Int
listAsStream val = if val then CL.sourceList [1..10] else throw $ MyException "Value"
conduitWhatever :: Sink Int IO ()
conduitWhatever = awaitForever $ liftIO . print
main :: IO ()
main = catchC (listAsStream False) handler $$ conduitWhatever
handler :: MyException -> Source IO Int
handler _= catchC (listAsStream True) handler
我很确定我误解了catchC
是如何运作的。谁能解释一下我做错了什么?
非常感谢!
答案 0 :(得分:5)
您对catchC
的使用是正确的;问题是throw
的使用,它引入了一个不精确的异常,而不是一个正确的IO
异常。如果您改为使用:
liftIO $ throwIO $ MyException "Value"
您的程序按预期工作。