Skip to content

Commit cd0bbdf

Browse files
Unwrap completion exception for legacy async handling
Closes #383 Co-authored-by: bhaveshthakker <bhaveshthakker111@gmail.com>
1 parent 60e75e5 commit cd0bbdf

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/main/java/org/xbill/DNS/Resolver.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.Collections;
1010
import java.util.List;
1111
import java.util.concurrent.CompletableFuture;
12+
import java.util.concurrent.CompletionException;
1213
import java.util.concurrent.CompletionStage;
1314
import java.util.concurrent.ExecutionException;
1415
import java.util.concurrent.Executor;
@@ -239,11 +240,16 @@ default Object sendAsync(Message query, ResolverListener listener) {
239240
(result, throwable) -> {
240241
if (throwable != null) {
241242
Exception exception;
243+
if (throwable instanceof CompletionException && throwable.getCause() != null) {
244+
throwable = throwable.getCause();
245+
}
246+
242247
if (throwable instanceof Exception) {
243248
exception = (Exception) throwable;
244249
} else {
245250
exception = new Exception(throwable);
246251
}
252+
247253
listener.handleException(id, exception);
248254
return null;
249255
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
package org.xbill.DNS;
3+
4+
import static org.assertj.core.api.Assertions.assertThat;
5+
import static org.junit.jupiter.api.Assertions.fail;
6+
7+
import java.net.UnknownHostException;
8+
import java.time.Duration;
9+
import java.util.concurrent.CompletionException;
10+
import java.util.concurrent.CountDownLatch;
11+
import java.util.concurrent.TimeUnit;
12+
import org.junit.jupiter.api.Test;
13+
14+
class ResolverTest {
15+
@Test
16+
@SuppressWarnings("deprecation")
17+
void resolverListenerExceptionUnwrap() throws InterruptedException, UnknownHostException {
18+
// 1. Point to a blackhole address from RFC 5737 TEST-NET-1 to ensure a timeout
19+
SimpleResolver resolver = new SimpleResolver("192.0.2.1");
20+
resolver.setTimeout(Duration.ofSeconds(2));
21+
22+
Message query =
23+
Message.newQuery(
24+
Record.newRecord(Name.fromConstantString("example.com."), Type.A, DClass.IN));
25+
CountDownLatch latch = new CountDownLatch(1);
26+
27+
// 2. Use the async method with a listener
28+
resolver.sendAsync(
29+
query,
30+
new ResolverListener() {
31+
@Override
32+
public void receiveMessage(Object id, Message m) {
33+
fail("Received message (should not happen)");
34+
latch.countDown();
35+
}
36+
37+
@Override
38+
public void handleException(Object id, Exception ex) {
39+
// 3. Observe the exception type
40+
assertThat(ex).isNotInstanceOf(CompletionException.class);
41+
latch.countDown();
42+
}
43+
});
44+
45+
latch.await(5, TimeUnit.SECONDS);
46+
}
47+
}

0 commit comments

Comments
 (0)