Skip to content

Commit 3d3d128

Browse files
authored
Merge pull request #1039 from enniokerber/feature/channel-abort-remove-throws
feat(Channel): Remove checked exception from interface Channel.abort(...) as it should silently discard any exceptions Fixes #434
2 parents e65bf79 + c3fc416 commit 3d3d128

File tree

4 files changed

+71
-23
lines changed

4 files changed

+71
-23
lines changed

src/main/java/com/rabbitmq/client/Channel.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,15 @@ public interface Channel extends ShutdownNotifier, AutoCloseable {
8989
* Forces the channel to close and waits for the close operation to complete.
9090
* Any encountered exceptions in the close operation are silently discarded.
9191
*/
92-
void abort() throws IOException;
92+
void abort();
9393

9494
/**
9595
* Abort this channel.
9696
*
9797
* Forces the channel to close and waits for the close operation to complete.
9898
* Any encountered exceptions in the close operation are silently discarded.
9999
*/
100-
void abort(int closeCode, String closeMessage) throws IOException;
100+
void abort(int closeCode, String closeMessage);
101101

102102
/**
103103
* Add a {@link ReturnListener}.

src/main/java/com/rabbitmq/client/impl/ChannelN.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -545,22 +545,18 @@ public void close(int closeCode, String closeMessage)
545545
/** Public API - {@inheritDoc} */
546546
@Override
547547
public void abort()
548-
throws IOException
549548
{
550549
abort(AMQP.REPLY_SUCCESS, "OK");
551550
}
552551

553552
/** Public API - {@inheritDoc} */
554553
@Override
555554
public void abort(int closeCode, String closeMessage)
556-
throws IOException
557555
{
558556
try {
559557
close(closeCode, closeMessage, true, null, true);
560-
} catch (IOException _e) {
561-
/* ignored */
562-
} catch (TimeoutException _e) {
563-
/* ignored */
558+
} catch (IOException | TimeoutException _e) {
559+
// abort() shall silently discard any exceptions
564560
}
565561
}
566562

src/main/java/com/rabbitmq/client/impl/recovery/AutorecoveringChannel.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,31 +80,35 @@ public void close(int closeCode, String closeMessage) throws IOException, Timeou
8080
}
8181

8282
@Override
83-
public void abort() throws IOException {
84-
try {
85-
executeAndClean(() -> delegate.abort());
86-
} catch (TimeoutException e) {
87-
// abort() ignores exceptions
88-
}
83+
public void abort() {
84+
this.delegate.abort();
85+
this.clean();
8986
}
9087

9188
@Override
92-
public void abort(int closeCode, String closeMessage) throws IOException {
93-
try {
94-
executeAndClean(() -> delegate.abort(closeCode, closeMessage));
95-
} catch (TimeoutException e) {
96-
// abort() ignores exceptions
89+
public void abort(int closeCode, String closeMessage) {
90+
this.delegate.abort(closeCode, closeMessage != null ? closeMessage : "");
91+
this.clean();
92+
}
93+
94+
/**
95+
* Cleans up the channel in the following way:
96+
* <p>
97+
* Removes every recorded consumer of the channel and finally unregisters the channel from
98+
* the underlying connection to not process any further traffic.
99+
*/
100+
private void clean() {
101+
for (String consumerTag : Utility.copy(consumerTags)) {
102+
this.deleteRecordedConsumer(consumerTag);
97103
}
104+
this.connection.unregisterChannel(this);
98105
}
99106

100107
private void executeAndClean(IoTimeoutExceptionRunnable callback) throws IOException, TimeoutException {
101108
try {
102109
callback.run();
103110
} finally {
104-
for (String consumerTag : Utility.copy(consumerTags)) {
105-
this.deleteRecordedConsumer(consumerTag);
106-
}
107-
this.connection.unregisterChannel(this);
111+
this.clean();
108112
}
109113
}
110114

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.rabbitmq.client.impl.recovery;
2+
3+
import org.junit.jupiter.api.BeforeEach;
4+
import org.junit.jupiter.api.Test;
5+
import org.mockito.Mock;
6+
import org.mockito.MockitoAnnotations;
7+
8+
import static org.mockito.Mockito.times;
9+
import static org.mockito.Mockito.verify;
10+
11+
public final class AutorecoveringChannelTest {
12+
13+
private AutorecoveringChannel channel;
14+
15+
@Mock
16+
private AutorecoveringConnection autorecoveringConnection;
17+
18+
@Mock
19+
private RecoveryAwareChannelN recoveryAwareChannelN;
20+
21+
@BeforeEach
22+
void setup() {
23+
MockitoAnnotations.openMocks(this);
24+
this.channel = new AutorecoveringChannel(autorecoveringConnection, recoveryAwareChannelN);
25+
}
26+
27+
@Test
28+
void abort() {
29+
this.channel.abort();
30+
verify(recoveryAwareChannelN, times(1)).abort();
31+
}
32+
33+
@Test
34+
void abortWithDetails() {
35+
int closeCode = 1;
36+
String closeMessage = "reason";
37+
this.channel.abort(closeCode, closeMessage);
38+
verify(recoveryAwareChannelN, times(1)).abort(closeCode, closeMessage);
39+
}
40+
41+
@Test
42+
void abortWithDetailsCloseMessageNull() {
43+
int closeCode = 1;
44+
this.channel.abort(closeCode, null);
45+
verify(recoveryAwareChannelN, times(1)).abort(closeCode, "");
46+
}
47+
48+
}

0 commit comments

Comments
 (0)