<div dir="ltr">I recently had to deal with a situation like this in a small web service which acts as an on-demand scraper for other sites. It runs on Servant, which uses ExceptT as of a few versions ago (EitherT before that), but for the remote calls it uses Wreq, which throws HttpException values. I needed to be able to report the details of remote errors rather than having them become a generic unhandled exception, so I was stuck with your option 0 -- but with ExceptT rather than Either, and it turns out ExceptT is pretty slick! Here's the resultant code:<div><br></div><div><a href="https://github.com/tejon/Meeseeks/blob/master/src/bin/MeeseeksBox.hs#L42-L48">https://github.com/tejon/Meeseeks/blob/master/src/bin/MeeseeksBox.hs#L42-L48</a><br></div><div><br></div><div>It's a one-route service so there's a bit of clutter in there that really should be abstracted out and/or done better. (Let's just pretend logE doesn't exist -- semantically, it doesn't!) But other than the bit I documented with a comment, it's entirely straightforward; and IIRC omitting that signature defaulted the type to IOException, which looks like what you want anyway.</div><div><br></div><div>tl;dr 0.5) ExceptT.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Sep 24, 2016 at 9:49 PM, Hillary Ryan <span dir="ltr"><<a href="mailto:hillaryryan92@gmail.com" target="_blank">hillaryryan92@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div>Dear Haskellers,<br><br></div>I've been working on variants of the following code:<br><br>connect_from_file :: String -> IO Connection<br>connect_from_file fi = do<br> s <- BL.readFile fi<br> cred <- (decode s :: Maybe Db_cred)<br> c <- connect . reformat_cred $ cred<br> return c<br><br></div>What
this code intends to do is read a config from a file in JSON,
decode the JSON, and then open a
connection based the decoded info. This code doesn't compile for several
reasons, but I've left it in this form because I believe it is the most
convenient for approaching my question:<br></div><br></div>How should I handle errors here?<br><br></div>Both
readFile (from Bytestring) and connect (from mysql.simple) throw
exceptions when things don't go their way, and decode uses maybe. I see
four ways of handling these errors:<br><br>0) <i>All typed errors: </i>I
could "capture" all the exceptions in Either types and use an EitherIO
monad or transformer to automatically abort when a Left value appears.
Now my function looks like: String -> IO (Either MyErrorType
Connection)<br></div>1) <i>All exceptions: </i>I could throw an exception if Nothing appears during decoding. The function looks the same: String -> IO Connection <br></div>2) <i>A mix</i>:
I could leave the connect and readFile functions alone, but return IO
(Nothing) if the decoding doesn't work out. Now we have: String -> IO
(Maybe Connection)<br></div>3) Not 0)-2)<br><div><br></div><div>So what is the proper way to do things?<br><br></div><div>Many Thanks,<br></div><div>Hillary<br></div><div><br><br></div>PS For what it is worth, I have read:<br>0) <a href="https://www.schoolofhaskell.com/user/commercial/content/exceptions-best-practices" target="_blank">https://www.schoolofhaskell.co<wbr>m/user/commercial/content/exce<wbr>ptions-best-practices</a> . I'd love to get feedback on how to apply this article to my question if it is appropriate.<br>1) <a href="https://lexi-lambda.github.io/blog/2016/06/12/four-months-with-haskell/" target="_blank">https://lexi-lambda.github.io/<wbr>blog/2016/06/12/four-months-wi<wbr>th-haskell/</a>
. From this article and others, I get the sense that there is great
confusion in the community as to how to handle errors correctly, and
worse yet, that different approaches are not easily compatible. </div>
<br>______________________________<wbr>_________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div>