无法从Conduit中的错误中恢复

时间:2015-01-21 01:47:38

标签: haskell conduit

我试图了解如何捕获管道中引发的错误。我相信通过在管道上应用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是如何运作的。谁能解释一下我做错了什么?

非常感谢!

1 个答案:

答案 0 :(得分:5)

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

liftIO $ throwIO $ MyException "Value"

您的程序按预期工作。