[rabbitmq-discuss] Strange reaction to publishing message with invalid expiration.
Simon MacMullen
simon at rabbitmq.com
Tue Mar 19 15:13:34 GMT 2013
Hi James. Yes, the basicPublish() invocation is not guaranteed to throw
an exception, since it's not synchronous - the message may not have
reached the server (or even left the client) by the time the method
returns. An exception will get thrown at some point later. If you need
to ensure that you find out about errors immediately you can close the
channel (and create a new one), invoke any synchronous AMQP method
(almost anything apart from basic.publish), or wait for confirms.
Cheers, Simon
On 19/03/13 14:59, James Gardner wrote:
> Didn't get a response to email below, sending again in hopes someone can
> answer...
>
> ==============
>
> Ok thanks, good to know. If that's how AMQP handles errors, that part's
> fine, and I'm used to PHP extensions not dealing with things correctly
> :), but I don't appear to be getting an exception when my Java code
> reaches:
> channel.basicPublish("e.test", "", props, "Hi!!!".getBytes());
> That statement, along with everything else (including the call to
> consume, which *does* throw an exception just fine) is inside a try
> {...} catch (Exception e) {...} .
> If you say I should be getting an exception, then I cannot explain why I
> am not.
> Here, I'll just include the code. All of this is just inside a main
> function in a Test class (I took out the consume part):
>
> try {
> ConnectionFactory factory = new ConnectionFactory();
> factory.setUri("amqp://user:pwd@amqp1.ourserver.gov/ourvhost");
> Connection conn = factory.newConnection();
>
> Channel channel = conn.createChannel();
>
> BasicProperties props = new BasicProperties
> .Builder()
> .expiration("trete")
> .build();
>
> channel.basicPublish("e.test", "", props, "Hi!!!".getBytes());
>
>
> }
> catch (Exception e) {
> System.out.println("Threw exception: ");
> e.printStackTrace(System.out);
> }
>
> My Java is a little rusty so forgive me if I am missing something.
> Am I supposed to get an IOException if the publish fails due to the bad
> header, or only if the channel had been closed before I do the publish
> or if I tried to use the channel again after the bad publish? The
> Javadocs seem vague on this.
>
> - James
>
>
> On 03/12/2013 11:12 AM, Simon MacMullen wrote:
>> Well, the channel is getting closed with an error message (same as it
>> would be for an illegal user_id in fact). That's AMQP's approach to
>> error handling.
>>
>> You should be able to see an IOException getting thrown in the Java
>> client, with a more descriptive cause property, or you can register a
>> ShutdownListener. I have no idea how the PHP client signals errors I'm
>> afraid.
>>
>> Cheers, Simon
>>
>> On 12/03/13 14:49, James Gardner wrote:
>>>
>>> Hi,
>>> I found a behavior which, to me at least, acts more like a bug than a
>>> feature...
>>> It seems that when you publish a message with an invalid expiration
>>> string (eg. "blah"), it renders that channel inoperable for consume
>>> operations afterwards. I would think it should just discard the message.
>>> In the official Java client, something closes the channel, although I
>>> don't get any exception until I try to use it for the ensuing consume
>>> operation.
>>> In the PHP AMQP client (this one:
>>> http://www.php.net/manual/en/book.amqp.php), the channel stays open but
>>> when you execute $queue->consume(...) and look in the management
>>> interface you can see it has not registered as a consumer on the queue
>>> of interest.
>>> Given the commonalities, I assume these are different client
>>> interpretations of the same broker behavior. I am not using transactions
>>> or publisher confirms or anything fancy. I am less familiar with the
>>> Java client so perhaps I am missing some sort of error handling?
>>>
>>> RabbitMQ version: RabbitMQ 3.0.3, Erlang R14B04 on RHEL 6.4
>>> PHP AMQP version is 1.0.1 (admittedly a little outdated)
>>> Java client is version: 3.0.3
>>>
>>> I can provide code for either client if you would like but I imagine you
>>> can replicate it easily just by establishing a connection, then a single
>>> channel, then publishing the 'bad' msg to a topic exchange, then trying
>>> to consume off a queue bound to that exchange with '#'.
>>> When you change expiration to a valid string integer, everything works
>>> as you would wish.
>>>
>>> Of course one answer, as the doctor joke goes, is to not 'move your arm
>>> like that'. Which is fine so long as there's a choice, but if I were
>>> creating messages and taking the expiration from a source outside my
>>> program (eg. database), this error might occur at some point if the data
>>> were bad. I could/should(?) sanitize/verify first of course, the point
>>> is more that I thought the typical broker reaction to illegal data was
>>> to deal with it 'silently' (as it does with an illegal user_id, for
>>> example) rather than effectively make the channel unusable.
>>> Is there a different way I (or the client code) should be handling this
>>> or is this an unexpected broker behavior?
>>> Thanks,
>>>
>>> James Gardner
>>> NWS - Internet Dissemination System
>>>
>>>
>>> _______________________________________________
>>> rabbitmq-discuss mailing list
>>> rabbitmq-discuss at lists.rabbitmq.com
>>> https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
>>
>>
>
--
Simon MacMullen
RabbitMQ, VMware
More information about the rabbitmq-discuss
mailing list