<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Nov 5, 2012 at 9:51 PM, Michael Snoyman <span dir="ltr">&lt;<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="im"><p><br>
On Nov 5, 2012 2:42 PM, &quot;Hiromi ISHII&quot; &lt;<a href="mailto:konn.jinro@gmail.com" target="_blank">konn.jinro@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; Hi, there<br>
&gt;<br>
&gt; On 2012/11/01, at 21:23, Michael Snoyman wrote:<br>
&gt;<br>
&gt; &gt; 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:<br>
&gt; &gt;<br>
&gt; &gt; * Catch exceptions before `lift`ing.<br>
&gt; &gt; * Catch exceptions thrown from the entire Pipe.<br>
&gt; &gt;<br>
&gt; &gt; 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.<br>
&gt;<br>
&gt; Thanks. In my case, used library is relatively small so I can rewrite it to ignore exception before lifting.<br>
&gt; But I think it is more convenient doing the same thing without modifying existing code.<br>
&gt;<br>
&gt; The second choice does not match my case because it cannot resume the process from the place just after an exception occurred.</p>
</div><p>I agree that it would be great if conduit could meet your use case better. I haven&#39;t spent enough cycles looking at this yet to determine if the reason we don&#39;t have this support is a limitation in the conduit approach itself, or just a limitation in what I was able to implement so far. If you can think of a way to implement more fine-grained exception handling (or anyone else for that matter), I&#39;d love to hear about it.</p>



<p></p><div class="im">&gt; &gt; 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.<br>
&gt;<br>
&gt; The type of the first argument of `transPipe` should be general, so I think we can&#39;t compose it with `catch` function.<br><br></div>That makes sense.<div class="im"><br><br>
&gt; -- Hiromi ISHII<br>
&gt; <a href="mailto:konn.jinro@gmail.com" target="_blank">konn.jinro@gmail.com</a><br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>
&gt; <a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div><p></p>
</div>
</blockquote></div>Sorry, small follow-up. It&#39;s certainly possible to make some kind of catching function, e.g.:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">catchPipe :: (MonadBaseControl IO m, Exception e) =&gt; Pipe l i o u m r -&gt; (e -&gt; Pipe l i o u m r) -&gt; Pipe l i o u m r</div>

<div class="gmail_extra">catchPipe (HaveOutput p c o) f = HaveOutput (catchPipe p f) c o</div><div class="gmail_extra">catchPipe (NeedInput p c) f = NeedInput (flip catchPipe f . p) (flip catchPipe f . c)</div><div class="gmail_extra">

catchPipe (Done r) _ = Done r</div><div class="gmail_extra">catchPipe (PipeM mp) f = PipeM $ Control.Exception.Lifted.catch (liftM (flip catchPipe f) mp) (return . f)</div><div class="gmail_extra">catchPipe (Leftover p l) f = Leftover (catchPipe p f) l</div>

<div><br></div><div>I&#39;m just not certain how useful this is in practice, as it doesn&#39;t really give you any information on what else that Pipe was about to perform. So you can&#39;t really just pick up where you left off.</div>

<div><br></div><div>Michael</div></div></div>