diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/Neo4jException.java b/driver/src/main/java/org/neo4j/driver/exceptions/Neo4jException.java index 1cffc7b304..a9eaa5e12a 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/Neo4jException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/Neo4jException.java @@ -23,7 +23,7 @@ * * @since 1.0 */ -public abstract class Neo4jException extends RuntimeException { +public class Neo4jException extends RuntimeException { private static final long serialVersionUID = -80579062276712566L; private final String code; diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java b/driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java index 71bda0cd87..e16570e332 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java @@ -18,7 +18,6 @@ */ package org.neo4j.driver.internal.util; -import io.netty.util.internal.PlatformDependent; import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.stream.Stream; @@ -115,7 +114,13 @@ public static void rethrowAsyncException(ExecutionException e) { .toArray(StackTraceElement[]::new); error.setStackTrace(currentStackTrace); - PlatformDependent.throwException(error); + RuntimeException exception; + if (error instanceof RuntimeException) { + exception = (RuntimeException) error; + } else { + exception = new Neo4jException("Driver execution failed", error); + } + throw exception; } private static boolean isProtocolViolationError(Neo4jException error) { diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ErrorUtilTest.java b/driver/src/test/java/org/neo4j/driver/internal/util/ErrorUtilTest.java index 8a1e25eef4..21d0e21419 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ErrorUtilTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ErrorUtilTest.java @@ -24,12 +24,18 @@ import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; import static org.neo4j.driver.internal.util.ErrorUtil.isFatal; import static org.neo4j.driver.internal.util.ErrorUtil.newConnectionTerminatedError; import static org.neo4j.driver.internal.util.ErrorUtil.newNeo4jError; +import static org.neo4j.driver.internal.util.ErrorUtil.rethrowAsyncException; import java.io.IOException; +import java.net.UnknownHostException; +import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.Test; import org.neo4j.driver.exceptions.AuthenticationException; import org.neo4j.driver.exceptions.AuthorizationExpiredException; @@ -195,4 +201,16 @@ void shouldMapTransientTransactionLockClientStoppedToClientException() { assertEquals("Neo.ClientError.Transaction.LockClientStopped", error.code()); assertEquals(message, error.getMessage()); } + + @Test + void shouldWrapCheckedExceptionsInNeo4jExceptionWhenRethrowingAsyncException() { + ExecutionException ee = mock(ExecutionException.class); + UnknownHostException uhe = mock(UnknownHostException.class); + given(ee.getCause()).willReturn(uhe); + given(uhe.getStackTrace()).willReturn(new StackTraceElement[0]); + + Neo4jException actual = assertThrows(Neo4jException.class, () -> rethrowAsyncException(ee)); + + assertEquals(actual.getCause(), uhe); + } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/FuturesTest.java b/driver/src/test/java/org/neo4j/driver/internal/util/FuturesTest.java index b6256e2c77..01254def71 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/FuturesTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/FuturesTest.java @@ -44,6 +44,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.internal.async.connection.EventLoopGroupFactory; class FuturesTest { @@ -177,8 +178,8 @@ void shouldThrowInBlockingGetWhenFutureThrowsCheckedException() { CompletableFuture future = new CompletableFuture<>(); future.completeExceptionally(error); - Exception e = assertThrows(Exception.class, () -> Futures.blockingGet(future)); - assertEquals(error, e); + Neo4jException e = assertThrows(Neo4jException.class, () -> Futures.blockingGet(future)); + assertEquals(error, e.getCause()); } @Test