Skip to content

feat(Channel): Remove checked exception from interface Channel.abort(...) as it should silently discard any exceptions #1039

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/com/rabbitmq/client/Channel.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ public interface Channel extends ShutdownNotifier, AutoCloseable {
* Forces the channel to close and waits for the close operation to complete.
* Any encountered exceptions in the close operation are silently discarded.
*/
void abort() throws IOException;
void abort();

/**
* Abort this channel.
*
* Forces the channel to close and waits for the close operation to complete.
* Any encountered exceptions in the close operation are silently discarded.
*/
void abort(int closeCode, String closeMessage) throws IOException;
void abort(int closeCode, String closeMessage);

/**
* Add a {@link ReturnListener}.
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/com/rabbitmq/client/impl/ChannelN.java
Original file line number Diff line number Diff line change
Expand Up @@ -545,22 +545,18 @@ public void close(int closeCode, String closeMessage)
/** Public API - {@inheritDoc} */
@Override
public void abort()
throws IOException
{
abort(AMQP.REPLY_SUCCESS, "OK");
}

/** Public API - {@inheritDoc} */
@Override
public void abort(int closeCode, String closeMessage)
throws IOException
{
try {
close(closeCode, closeMessage, true, null, true);
} catch (IOException _e) {
/* ignored */
} catch (TimeoutException _e) {
/* ignored */
} catch (IOException | TimeoutException _e) {
// abort() shall silently discard any exceptions
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,31 +80,35 @@ public void close(int closeCode, String closeMessage) throws IOException, Timeou
}

@Override
public void abort() throws IOException {
try {
executeAndClean(() -> delegate.abort());
} catch (TimeoutException e) {
// abort() ignores exceptions
}
public void abort() {
this.delegate.abort();
this.clean();
}

@Override
public void abort(int closeCode, String closeMessage) throws IOException {
try {
executeAndClean(() -> delegate.abort(closeCode, closeMessage));
} catch (TimeoutException e) {
// abort() ignores exceptions
public void abort(int closeCode, String closeMessage) {
this.delegate.abort(closeCode, closeMessage != null ? closeMessage : "");
this.clean();
}

/**
* Cleans up the channel in the following way:
* <p>
* Removes every recorded consumer of the channel and finally unregisters the channel from
* the underlying connection to not process any further traffic.
*/
private void clean() {
for (String consumerTag : Utility.copy(consumerTags)) {
this.deleteRecordedConsumer(consumerTag);
}
this.connection.unregisterChannel(this);
}

private void executeAndClean(IoTimeoutExceptionRunnable callback) throws IOException, TimeoutException {
try {
callback.run();
} finally {
for (String consumerTag : Utility.copy(consumerTags)) {
this.deleteRecordedConsumer(consumerTag);
}
this.connection.unregisterChannel(this);
this.clean();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.rabbitmq.client.impl.recovery;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

public final class AutorecoveringChannelTest {

private AutorecoveringChannel channel;

@Mock
private AutorecoveringConnection autorecoveringConnection;

@Mock
private RecoveryAwareChannelN recoveryAwareChannelN;

@BeforeEach
void setup() {
MockitoAnnotations.openMocks(this);
this.channel = new AutorecoveringChannel(autorecoveringConnection, recoveryAwareChannelN);
}

@Test
void abort() {
this.channel.abort();
verify(recoveryAwareChannelN, times(1)).abort();
}

@Test
void abortWithDetails() {
int closeCode = 1;
String closeMessage = "reason";
this.channel.abort(closeCode, closeMessage);
verify(recoveryAwareChannelN, times(1)).abort(closeCode, closeMessage);
}

@Test
void abortWithDetailsCloseMessageNull() {
int closeCode = 1;
this.channel.abort(closeCode, null);
verify(recoveryAwareChannelN, times(1)).abort(closeCode, "");
}

}