2015-01-21 46 views
2

我想了解如何捕获管道内引发的错误。我相信,通过在管道上应用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是如何工作的。任何人都可以解释我做错了什么吗?

非常感谢!

回答

5

您对catchC的使用是正确的;问题是throw的使用,它引入了一个不精确的异常,而不是正确的异常。如果您改为使用:

liftIO $ throwIO $ MyException "Value" 

您的程序按预期工作。