IO exception not being caught

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

IO exception not being caught

Joel Reymont
Folks,

I have a problem catching my IO exception with the code below. The  
intent is to catch either the IO exception from connectTo (connection  
refused, etc.) or the timeout.

type EngineState = ErrorT String (StateT World IO)

fromIOError err = ioeGetErrorString err

liftIOTrap :: IO a -> EngineState a
liftIOTrap io =
     do mx <- liftIO (do x <- io
                         return (return x)
                                    `catchError`
                                    (\e -> return (throwError
                                                   (fromIOError e))))
        mx

timeout secs fun =
     do resultVar <- newEmptyMVar
        threadId <- forkIO $
                    do result <- fun
                       putMVar resultVar result
        forkIO $ do threadDelay (secs * 1000000)
                    throwError $ userError "Timeout"
        maybeResult <- takeMVar resultVar
        killThread threadId
        return maybeResult

connect_ :: HostName -> Int -> IO Handle
connect_ h p = connectTo h $ PortNumber $ fromIntegral p

connect :: HostName -> Int -> EngineState ()
connect host port =
     do w <- get
        let secs = timeout_seconds w
        h <- liftIOTrap $ timeout secs $ connect_ host port
        trace $ "Connection established, h: " ++ show h
...

        Thanks, Joel

--
http://wagerlabs.com/





_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: IO exception not being caught

Joel Reymont
I fixed up my timeout function to look like this:

timeout :: forall a.Show a => Int -> IO a -> IO a
timeout secs fun =
     mdo mvar <- newEmptyMVar
         tid1 <- forkIO $ do result <- try fun
                             putMVar mvar $
                                     either (Left . show) (Right . id)
                                            result
                             killThread tid2
         tid2 <- forkIO $ do threadDelay (secs * 1000000)
                             putMVar mvar (Left "timeout")
                             killThread tid1
         maybeResult <- takeMVar mvar
         case maybeResult of
           Right a -> return a
           Left b -> fail b

But the IOError is still not being caught by liftIOTrap.

Any clues?

        Thanks, Joel

On Nov 16, 2005, at 1:27 PM, Joel Reymont wrote:

> Folks,
>
> I have a problem catching my IO exception with the code below. The  
> intent is to catch either the IO exception from connectTo  
> (connection refused, etc.) or the timeout.
>
> type EngineState = ErrorT String (StateT World IO)
>
> fromIOError err = ioeGetErrorString err
>
> liftIOTrap :: IO a -> EngineState a
> liftIOTrap io =
>     do mx <- liftIO (do x <- io
>                         return (return x)
>                                    `catchError`
>                                    (\e -> return (throwError
>                                                   (fromIOError e))))
>        mx
>

--
http://wagerlabs.com/





_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: IO exception not being caught

Joel Reymont
After almost two months with Haskell I'm starting to understand why  
its use is not as widespread as... well pick a favorite language of  
your own. My issue was that of indentation.

Compare this working version:

liftIOTrap io =
     do mx <- liftIO (do x <- io
                         return (return x)
                      `catchError`
                      (\e -> do let x = fromIOError e
                                trace_ $ "Caught " ++ x
                                return $ throwError x
                      ))
        mx

With the one below

On Nov 16, 2005, at 2:27 PM, Joel Reymont wrote:

>> liftIOTrap io =
>>     do mx <- liftIO (do x <- io
>>                         return (return x)
>>                                    `catchError`
>>                                    (\e -> return (throwError
>>                                                   (fromIOError e))))
>>        mx

--
http://wagerlabs.com/





_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

RE: Re: IO exception not being caught

Simon Peyton Jones
In reply to this post by Joel Reymont
Indeed!  I always use braces and semicolons with do-notation.  You are
free to do so too!  Nothing requires you to use layout. Indeed, you can
freely mix the two.

Simon

| -----Original Message-----
| From: [hidden email]
[mailto:[hidden email]] On Behalf Of Joel
| Reymont
| Sent: 16 November 2005 15:37
| To: Haskell Cafe
| Subject: [Haskell-cafe] Re: IO exception not being caught
|
| After almost two months with Haskell I'm starting to understand why
| its use is not as widespread as... well pick a favorite language of
| your own. My issue was that of indentation.
|
| Compare this working version:
|
| liftIOTrap io =
|      do mx <- liftIO (do x <- io
|                          return (return x)
|                       `catchError`
|                       (\e -> do let x = fromIOError e
|                                 trace_ $ "Caught " ++ x
|                                 return $ throwError x
|                       ))
|         mx
|
| With the one below
|
| On Nov 16, 2005, at 2:27 PM, Joel Reymont wrote:
|
| >> liftIOTrap io =
| >>     do mx <- liftIO (do x <- io
| >>                         return (return x)
| >>                                    `catchError`
| >>                                    (\e -> return (throwError
| >>                                                   (fromIOError
e))))
| >>        mx
|
| --
| http://wagerlabs.com/
|
|
|
|
|
| _______________________________________________
| Haskell-Cafe mailing list
| [hidden email]
| http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: layout problem

Christian Maeder
Simon Peyton-Jones wrote:
> Indeed!  I always use braces and semicolons with do-notation.  You are
> free to do so too!  Nothing requires you to use layout. Indeed, you can
> freely mix the two.

I would not recommend braces and semicolons, because these allow a bad
layout (easy to parse for a compiler, but hard to read for a human),
unless you invest the time to make a tidy layout despite the braces and
semicolons. (So why not only make a tidy layout?)

Surely, a different layout may change your semantics (in rare cases). A
missplaced "_ -> error ..." case usually causes a pattern warning.

> | >> liftIOTrap io =
> | >>     do mx <- liftIO (do x <- io
> | >>                         return (return x)
> | >>                                    `catchError`
> | >>                                    (\e -> return (throwError
> | >>                                                   (fromIOError
> e))))

I'ld rather avoid the infix `catchError' and write:

   liftIO $ catchError
     (do ...
              ) $ \e ->

Cheers Christian
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Re: IO exception not being caught

Bulat Ziganshin
In reply to this post by Joel Reymont
Hello Joel,

Wednesday, November 16, 2005, 6:37:25 PM, you wrote:

JR> After almost two months with Haskell I'm starting to understand why  
JR> its use is not as widespread as... well pick a favorite language of  
JR> your own. My issue was that of indentation.

just enclose potentially problematic "do ..." in parentheses:

JR> liftIOTrap io =
JR>      do mx <- liftIO (do x <- io
JR>                          return (return x)

can be written as

do mx <- liftIO ((do x <- io
                    return (return x))

and after that you can put `catchError` to any position in the line




--
Best regards,
 Bulat                            mailto:[hidden email]



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: layout problem

Stefan Monnier
In reply to this post by Christian Maeder
>> Indeed!  I always use braces and semicolons with do-notation.  You are
>> free to do so too!  Nothing requires you to use layout. Indeed, you can
>> freely mix the two.

> I would not recommend braces and semicolons, because these allow a bad
> layout (easy to parse for a compiler, but hard to read for a human), unless
> you invest the time to make a tidy layout despite the braces and
> semicolons. (So why not only make a tidy layout?)

Unless you use a simplistic text editor, the braces and semi-colons allow
the text editor to do the layout for you.  While I find the layout notation
attractively clean, I find the redundancy of autolayout+braces+semicolons to
save me from a lot of trouble.


        Stefan

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Re: layout problem

Cale Gibbard
On 16/11/05, Stefan Monnier <[hidden email]> wrote:

> >> Indeed!  I always use braces and semicolons with do-notation.  You are
> >> free to do so too!  Nothing requires you to use layout. Indeed, you can
> >> freely mix the two.
>
> > I would not recommend braces and semicolons, because these allow a bad
> > layout (easy to parse for a compiler, but hard to read for a human), unless
> > you invest the time to make a tidy layout despite the braces and
> > semicolons. (So why not only make a tidy layout?)
>
> Unless you use a simplistic text editor, the braces and semi-colons allow
> the text editor to do the layout for you.  While I find the layout notation
> attractively clean, I find the redundancy of autolayout+braces+semicolons to
> save me from a lot of trouble.
>
If your editor is a little smarter still, it can do the Haskell layout
without braces automatically too. The emacs mode helps with this.
Yi/hIDE should be able to do it perfectly once it's in a generally
usable state. :)

 - Cale
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Re: layout problem

Ben Franksen-2
On Thursday 17 November 2005 03:44, Cale Gibbard wrote:

> On 16/11/05, Stefan Monnier <[hidden email]> wrote:
> > >> Indeed!  I always use braces and semicolons with do-notation.
> > >> You are free to do so too!  Nothing requires you to use layout.
> > >> Indeed, you can freely mix the two.
> > >
> > > I would not recommend braces and semicolons, because these allow
> > > a bad layout (easy to parse for a compiler, but hard to read for
> > > a human), unless you invest the time to make a tidy layout
> > > despite the braces and semicolons. (So why not only make a tidy
> > > layout?)
> >
> > Unless you use a simplistic text editor, the braces and semi-colons
> > allow the text editor to do the layout for you.  While I find the
> > layout notation attractively clean, I find the redundancy of
> > autolayout+braces+semicolons to save me from a lot of trouble.
>
> If your editor is a little smarter still, it can do the Haskell
> layout without braces automatically too. The emacs mode helps with
> this. Yi/hIDE should be able to do it perfectly once it's in a
> generally usable state. :)

Hmm, how would your super intelligent text editor layout the ambigous
example of the OP? Well, never mind: either way might be the wrong one,
depending on what the program is /supposed/ to do.

Ben
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

RE: layout problem

Simon Marlow
In reply to this post by Christian Maeder
On 16 November 2005 17:15, Christian Maeder wrote:

> Simon Peyton-Jones wrote:
>> Indeed!  I always use braces and semicolons with do-notation.  You
>> are free to do so too!  Nothing requires you to use layout. Indeed,
>> you can freely mix the two.
>
> I would not recommend braces and semicolons, because these allow a bad
> layout (easy to parse for a compiler, but hard to read for a human),
> unless you invest the time to make a tidy layout despite the braces
> and semicolons. (So why not only make a tidy layout?)
>
> Surely, a different layout may change your semantics (in rare cases).
> A missplaced "_ -> error ..." case usually causes a pattern warning.
>
>>>>> liftIOTrap io =
>>>>>     do mx <- liftIO (do x <- io
>>>>>                         return (return x)
>>>>>                                    `catchError`
>>>>>                                    (\e -> return (throwError
>>>>>                                                   (fromIOError
>>>>> e))))
>
> I'ld rather avoid the infix `catchError' and write:
>
>    liftIO $ catchError
>      (do ...
>               ) $ \e ->

I generally prefer to use the "handle" variants rather than "catch":

    liftIO $
       handle my_handler $ do
          x <- io
          return (return x)
    where
      my_handler e = return (throwError (fromIOError e))

Don't be afraid to name things if it makes your code easier to read.

Cheers,
        Simon
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Re: layout problem

Ketil Malde
In reply to this post by Ben Franksen-2
Benjamin Franksen wrote:

>>If your editor is a little smarter still, it can do the Haskell
>>layout without braces automatically too. The emacs mode helps with
>>this. Yi/hIDE should be able to do it perfectly once it's in a
>>generally usable state. :)
>>    
>>
>Hmm, how would your super intelligent text editor layout the ambigous
>example of the OP? Well, never mind: either way might be the wrong one,
>depending on what the program is /supposed/ to do.
>
It would alternate between them as you push TAB, of course.

-k
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Re: layout problem

Philippa Cowderoy
In reply to this post by Cale Gibbard
On Wed, 16 Nov 2005, Cale Gibbard wrote:

> If your editor is a little smarter still, it can do the Haskell layout
> without braces automatically too. The emacs mode helps with this.
> Yi/hIDE should be able to do it perfectly once it's in a generally
> usable state. :)
>

The one I'm looking forward to is an editor that'll de-layout code and
show me the resulting braces and semicolons (albeit highlighted
differently to ones I put there myself).

--
[hidden email]

Society does not owe people jobs.
Society owes it to itself to find people jobs.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Re: layout problem

Ben Franksen-2
In reply to this post by Ketil Malde
On Thursday 17 November 2005 11:42, Ketil Malde wrote:

> Benjamin Franksen wrote:
> >>If your editor is a little smarter still, it can do the Haskell
> >>layout without braces automatically too. The emacs mode helps with
> >>this. Yi/hIDE should be able to do it perfectly once it's in a
> >>generally usable state. :)
> >
> >Hmm, how would your super intelligent text editor layout the
> > ambigous example of the OP? Well, never mind: either way might be
> > the wrong one, depending on what the program is /supposed/ to do.
>
> It would alternate between them as you push TAB, of course.

Nice solution. Not fool-proof either: you need to know beforehand when
to try and ush TAB a second time; but probably ok. Ideal would be a
pop-up menu presenting all possible choices; the difficult part being
how to represent the choices so that one can easily find out which
corresponds to what one wants, and still manage to keep them to less
than a screenful of code ;-)

Ben
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe