[rabbitmq-discuss] AlreadyClosedException always sets hardError and initiatedByApplication to true

Jonathan Halterman jhalterman at gmail.com
Tue Oct 22 17:07:59 BST 2013

Comments below:

On Tue, Oct 22, 2013 at 7:46 AM, Steve Powell <steve at rabbitmq.com> wrote:

> On 22 Oct 2013, at 11:42, Steve Powell <steve at rabbitmq.com> wrote:
> Issuing a 'real work' call after closing the channel, like
> channel.basicConsume(), throws an AlreadyClosedException, claiming that
> the connection is closed, but conn.isOpen() still returns true.
> Well, it appears that the AlreadyClosedException produces the "clean
> connection shutdown" string when it is a hard error (which is correct). It
> is called by the (internal) 'channel.ensureIsOpen()' method (typically,
> if we are about to communicate across the channel).  But the reference in
> the exception is then to a Channel,

This is the workaround I've been using to determine if a Channel was closed
versus a Connection - by looking at what type the reference is.

> and although the exception implies that the connection has been closed, it
> hasn't.  This appears to contradict the hard error flag: which is supposed
> to mean the *connection* is closed.
> I guess this means that the bug is *the connection isn't closed by the
> application initiated call to a closed channel.*
> You could argue this particular channel error doesn't violate the
> protocol, so there is no reason to suppose that the connection would (or
> should) be closed, so it shouldn't be a hard error.  [The code comments
> imply that hardError==true implies that getReference() returns a
> Connection object, which is actually *not* true anyway.]
> As this thread stated right at the beginning (see subject), there is no
> provision in the code for issuing an AlreadyClosedException without it
> being a hard error.  If we could do this, the meaning of hardError would be
> preserved.
> As in the case of referring to a consumer that the client has no record
> of, the client code can often determine if the channel is already closed,
> and *not* risk any protocol violations before throwing the exception.  In
> these cases, it ought not to be a hard error: the connection can remain
> unaffected.

That would be ideal, if an AlreadyClosedException due to an invocation
against a closed Channel did not result in a Connection closure. The reason
is (as we've been discussing in a separate thread: Channel.basicPublish to
a non-existent exchange...) sometimes the client receives an
AlreadyClosedException *before* they are ever notified that the Channel was
closed. This happens if you're doing rapid basicPublish calls to a
non-existent exchange. Eventually basicPublish fails with an
AlreadyClosedException, but this often occurs before the Channel's
ShutdownListener is called. So the client has no fair way of avoiding the

So from my perspective, there are a few things I'd prefer to see out of all

- That AlreadyClosedExceptions be allowed to represent channels that were
already closed (as seems to be the case with the reference being set to a
- That an invocation against a Channel that has already been closed does
not result in the Connection being closed (as seems to be the case).
- That AlreadyClosedExceptions include the Method that originally cased the
closure as the shutdown reason (if any), such as 404. This would allow me
to determine why a basicPublish fails.


>   Steve Powell  [*Cell*: +44-7815-838-558] [RabbitMQ<http://www.rabbitmq.com/>
> ,* *Pivotal <http://gopivotal.com/>]
> *“L’enfer, c’est les autres.” *Sartre
> _______________________________________________
> rabbitmq-discuss mailing list
> rabbitmq-discuss at lists.rabbitmq.com
> https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20131022/c71cf200/attachment.htm>

More information about the rabbitmq-discuss mailing list