<div dir="ltr">Due to various technical reasons regarding the nature of conduit, you can&#39;t currently catch exceptions within the Pipe monad. You have two options:<div><br></div><div>* Catch exceptions before `lift`ing.</div>

<div>* Catch exceptions thrown from the entire Pipe.</div><div><br></div><div>Since the exceptions are always originating in the underlying monad, the first choice is certainly possible in theory, though may require reworking the library you&#39;re using a bit.</div>

<div><br></div><div>One other possibility that I haven&#39;t actually tried would be to use transPipe[1] to catch all of the exceptions, though I&#39;m not sure how well that would work in practice.</div><div><br></div><div>

If people have ideas on how to improve the exception handling facilities of conduit, please let me know.</div><div><br></div><div>Michael</div><div><br></div><div>[1] <a href="http://hackage.haskell.org/packages/archive/conduit/0.5.2.7/doc/html/Data-Conduit.html#v:transPipe">http://hackage.haskell.org/packages/archive/conduit/0.5.2.7/doc/html/Data-Conduit.html#v:transPipe</a></div>

</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Nov 1, 2012 at 6:26 AM, Hiromi ISHII <span dir="ltr">&lt;<a href="mailto:konn.jinro@gmail.com" target="_blank">konn.jinro@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi, there<br>
<br>
I&#39;m writing a program communicating with external process, which can be sometimes fail, using conduit and process-conduit package.<br>
<br>
Consider the following example, which reads paths from the config file, and passes their contents to external process, and output the results:<br>
<br>
```exc.hs<br>
module Main where<br>
import qualified Data.ByteString.Char8 as BS<br>
import           Data.Conduit<br>
import qualified Data.Conduit.Binary   as BC<br>
import qualified Data.Conduit.List     as LC<br>
import           Data.Conduit.Process<br>
<br>
main :: IO ()<br>
main = runResourceT $<br>
  BC.sourceFile &quot;paths.dat&quot; $$ BC.lines =$= myConduit =$= LC.mapM_ (unsafeLiftIO . BS.putStrLn)<br>
<br>
myConduit :: MonadResource m =&gt; Conduit BS.ByteString m BS.ByteString<br>
myConduit = awaitForever $ \path -&gt;<br>
  BC.sourceFile (BS.unpack path) =$= conduitCmd &quot;./sometimes-fail&quot;<br>
```<br>
<br>
```sometimes-fail.hs<br>
module Main where<br>
import System.Random<br>
<br>
main :: IO ()<br>
main = do<br>
  b &lt;- randomRIO (1,10 :: Int)<br>
  if b &lt; 9 then interact id else error &quot;error!&quot;<br>
```<br>
<br>
```paths.dat<br>
txt/a.dat<br>
txt/b.dat<br>
txt/c.dat<br>
...bra, bra, bra...<br>
```<br>
<br>
As you can see, `sometimes-fail` is a simple echoing program, but sometimes fail at random.<br>
<br>
Successful result is below:<br>
<br>
```<br>
$ ./exc<br>
this is a!<br>
<br>
this is b!<br>
<br>
this is c!<br>
<br>
this was d!<br>
<br>
this was e!<br>
<br>
and this is f.<br>
```<br>
<br>
but if `sometimes-fail` fails in some place, `exc` exits with exception like below:<br>
<br>
```<br>
$ ./exc<br>
this is a!<br>
<br>
this is b!<br>
<br>
this is c!<br>
sometimes-fail: error!<br>
```<br>
<br>
But I want to write the program acts like below:<br>
<br>
```<br>
$ ./exc<br>
this is a!<br>
<br>
this is b!<br>
<br>
this is c!<br>
sometimes-fail: error!<br>
this was e!<br>
<br>
and this is f.<br>
```<br>
<br>
that is, ignore the exception and continue to process remaining streams.<br>
<br>
So, the question is: how to handle the exception in `myConduit` and proceed to remaining works?<br>
<br>
In `conduit` package, `Pipe` type is not an instance of `MonadBaseControl IO` so it cannot handle exceptions within it.<br>
I think this is necessary to make `ResourceT` release resources correctly.<br>
<br>
So, how to write the Conduit that ignores some kind of exceptions and proceed to remaining works?<br>
One sometimes want to ignore the invalid input and/or output and just continue to process the remaining stream.<br>
<br>
One solution is that libraries using conduit provide &quot;failure-ignore&quot; version for all the `Pipe`s included in the library, but I think it is too heavy solution. It is ideal that `conduit` can package provides combinator that makes exsiting `Pipe`s &quot;failure-ignore&quot;.<br>


<br>
<br>
-- Hiromi ISHII<br>
<a href="mailto:konn.jinro@gmail.com">konn.jinro@gmail.com</a><br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br></div>