[Haskell-cafe] Error handling with safer-file-handling

Bas van Dijk v.dijk.bas at gmail.com
Mon Nov 15 17:39:10 EST 2010


On Sun, Nov 14, 2010 at 12:38 PM, Florian Weimer <fw at deneb.enyo.de> wrote:
> How am I supposed to write an exception handle for an invocation
> of System.IO.SaferFileHandles.openFile?
>
> Currently, I have got this:
>
>  case req of
>    Open path -> do
>      handle <-openFile (asAbsPath path) ReadMode
>      liftIO $ forcePut result Success
>      run handle
>
> Follwing safer-file-handling-examples, I rewrote it to:
>
>  case req of
>    Open path -> do
>      (do runRegionT $ do
>            handle <-openFile (asAbsPath path) ReadMode
>            liftIO $ forcePut result Success
>            run handle)
>      `catch` \(e :: IOException) -> do
>        liftIO $ forcePut result $ Failure $ show e
>
> (I would rather like to apply the handler to the openFile invocation
> only, but the above matches the example code more closely.)

You should be able to apply 'catch' directly to the openFile invocation.

Do note that a RegionT doesn't have an instance for MonadCatchIO
anymore. In regions-0.8[1] I switched to using MonadPeelIO from
monad-peel[2] instead. So import 'catch' from Control.Exception.Peel.

> But this gives me a nice error message:
>
> Handles.hs:48:17:
>    Could not deduce (Control.Monad.CatchIO.MonadCatchIO
>                        (RegionT s IO))
>      from the context ()
>      arising from a use of `catch' at Handles.hs:(48,17)-(54,50)
>    Possible fix:
>      add (Control.Monad.CatchIO.MonadCatchIO
>             (RegionT s IO)) to the context of
>        the polymorphic type `forall s. RegionT s pr α'
>      or add an instance declaration for
>         (Control.Monad.CatchIO.MonadCatchIO (RegionT s IO))
>    In the expression:
>          do { (do { runRegionT
>                   $ do { handle <- openFile (asAbsPath path) ReadMode;
>                          .... } }) }
>        `catch`
>          \ (e :: IOException)
>              -> do { liftIO $ forcePut result $ Failure $ show e }
>    In a case alternative:
>        Open path
>          -> do { (do { runRegionT $ do { ... } }) }
>           `catch`
>             \ (e :: IOException)
>                 -> do { liftIO $ forcePut result $ Failure $ show e }
>    In the expression:
>        case req of {
>          Open path
>            -> do { (do { runRegionT $ ... }) }
>             `catch`
>               \ (e :: IOException) -> do { ... }
>          Close -> return ()
>          _ -> liftIO $ forcePut result $ Failure "handle not open" }
>
> safer-file-handling-examples results in similar error messages, after
> applying the s/runTopRegion/runRegionT/ fix.

Thanks for reporting this!

I forgot to update the safer-file-handles-examples[3]. They should be fine now.

Regards,

Bas

[1] http://hackage.haskell.org/package/regions-0.8
[2] http://hackage.haskell.org/package/monad-peel-0.1
[3] darcs get http://code.haskell.org/~basvandijk/code/safer-file-handles-examples


More information about the Haskell-Cafe mailing list