[Haskell-beginners] AMQP and nested exception handlers

Alex alex323 at gmail.com
Tue May 12 06:10:50 UTC 2015


On Tue, 12 May 2015 05:24:32 +0000
Alexey Shmalko <rasen.dubi at gmail.com> wrote:

> Your issue is related to Lazy evaluation. Your function (lookupHeader)
> isn't actually evaluated before you call publishMsg or print. You
> need to put seq or deepseq to overcome this, or put your exception
> handler in place when your function is actually evaluated.
> Unfortunately, you haven't provided the calling code, so I have no
> specific suggestion. Just read some info on Lazy vs. Strict.
> 

Per your suggestion, I tried out deepseq, and it doesn't seem to be
working. Below is the code which sends the message to RMQ. As you've
noted, `req' is not fully evaluated at this point:

    publishMsg chan "" "the-queue"
      newMsg { msgDeliveryMode = Just Persistent
             , msgReplyTo      = Just cbQueue
             , msgBody         = encode req
             }

If I put this line above publishMsg, the problem still exists:

_ <- return $!! req

This is counter intuitive, because I would have thought that running
deepseq on req would fully evaluate it to NF, but that doesn't seem to
be the case.

> Parallel and Concurrent Programming in Haskell Chapter 2 [1] has a
> good description (just skip "The Eval Monad, rpar, and rseq" section
> and continue with deepseq).
> Here is a good chapter on exception [2], if you need one.
> 
> [1]: http://chimera.labs.oreilly.com/books/1230000000929/ch02.html
> [2]:
> http://chimera.labs.oreilly.com/books/1230000000929/ch08.html#sec_exceptions
> 
> On Tue, May 12, 2015 at 5:11 AM Alex <alex323 at gmail.com> wrote:
> 
> > Hi:
> >
> > I am writing a small application which receives HTTP requests,
> > translates them to JSON, and queues the requests using RabbitMQ.
> >
> > I am using exceptions to handle extreme cases, such as when a
> > client's HTTP request lacks a critical header:
> >
> > lookupHeader :: RequestHeaders -> HeaderName -> Text
> > lookupHeader hs h = decodeUtf8 $ fromMaybe notFound
> >                                            (lookup h hs)
> >   where
> >     notFound = throw $ MissingHeader $ decodeUtf8 $ original h
> >
> > The problem I am running in to is that the header isn't actually
> > looked up until I call the AMQP library's publishMsg function. If I
> > purposely do not supply a critical header, I get the following
> > error printed to the screen:
> >
> > ConnectionClosedException "ConnectionClosedException
> > \"UNEXPECTED_FRAME
> > - expected content header for class 60, got non content header frame
> > instead\""
> >
> > If I add the following line just above the publishMsg function (to
> > force evaluation), my exception handler is called successfully:
> >
> > print $ encode req
> >
> > As a result, I suspect that this is due to the fact that the "throw
> > MissingHeader" is getting captured by the AMQP library. What's the
> > best way to deal with this situation?
> >
> > --
> > Alex
> > _______________________________________________
> > Beginners mailing list
> > Beginners at haskell.org
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
> >



-- 
Alex


More information about the Beginners mailing list