This is an automated email from the ASF dual-hosted git repository.
isapego pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new bcfa3e2acd IGNITE-20871 Fix stack trace in client exceptions (#2845)
bcfa3e2acd is described below
commit bcfa3e2acda444c508d0b992919347cc022eb65f
Author: Igor Sapego <[email protected]>
AuthorDate: Tue Nov 21 13:48:42 2023 +0400
IGNITE-20871 Fix stack trace in client exceptions (#2845)
---
.../apache/ignite/lang/IgniteCheckedException.java | 9 +-
.../handler/ClientInboundMessageHandler.java | 3 +-
.../apache/ignite/internal/client/ClientUtils.java | 52 ++++++++-
.../ignite/internal/client/TcpClientChannel.java | 3 +-
.../internal/client/compute/ClientCompute.java | 8 +-
.../client/ClientKeyValueBinaryViewTest.java | 6 +
.../ignite/client/ClientKeyValueViewTest.java | 7 ++
.../apache/ignite/client/ClientRecordViewTest.java | 6 +
.../ignite/internal/client/ClientUtilsTest.java | 128 +++++++++++++++++++++
.../ignite/internal/util/ExceptionUtils.java | 11 --
.../runner/app/client/ItThinClientComputeTest.java | 9 +-
11 files changed, 211 insertions(+), 31 deletions(-)
diff --git
a/modules/api/src/main/java/org/apache/ignite/lang/IgniteCheckedException.java
b/modules/api/src/main/java/org/apache/ignite/lang/IgniteCheckedException.java
index aaccd9a4cb..0c90a4923b 100755
---
a/modules/api/src/main/java/org/apache/ignite/lang/IgniteCheckedException.java
+++
b/modules/api/src/main/java/org/apache/ignite/lang/IgniteCheckedException.java
@@ -25,6 +25,7 @@ import static
org.apache.ignite.lang.ErrorGroups.extractGroupCode;
import static org.apache.ignite.lang.util.TraceIdUtils.getOrCreateTraceId;
import java.util.UUID;
+import org.jetbrains.annotations.Nullable;
/**
* General Ignite exception. Used to indicate any error condition within a
node.
@@ -102,7 +103,7 @@ public class IgniteCheckedException extends Exception
implements TraceableExcept
* @param code Full error code.
* @param cause Optional nested exception (can be {@code null}).
*/
- public IgniteCheckedException(int code, Throwable cause) {
+ public IgniteCheckedException(int code, @Nullable Throwable cause) {
this(getOrCreateTraceId(cause), code, cause);
}
@@ -113,7 +114,7 @@ public class IgniteCheckedException extends Exception
implements TraceableExcept
* @param code Full error code.
* @param cause Optional nested exception (can be {@code null}).
*/
- public IgniteCheckedException(UUID traceId, int code, Throwable cause) {
+ public IgniteCheckedException(UUID traceId, int code, @Nullable Throwable
cause) {
super((cause != null) ? cause.getLocalizedMessage() : null, cause);
this.traceId = traceId;
@@ -128,7 +129,7 @@ public class IgniteCheckedException extends Exception
implements TraceableExcept
* @param message Detailed message.
* @param cause Optional nested exception (can be {@code null}).
*/
- public IgniteCheckedException(int code, String message, Throwable cause) {
+ public IgniteCheckedException(int code, String message, @Nullable
Throwable cause) {
this(getOrCreateTraceId(cause), code, message, cause);
}
@@ -140,7 +141,7 @@ public class IgniteCheckedException extends Exception
implements TraceableExcept
* @param message Detailed message.
* @param cause Optional nested exception (can be {@code null}).
*/
- public IgniteCheckedException(UUID traceId, int code, String message,
Throwable cause) {
+ public IgniteCheckedException(UUID traceId, int code, String message,
@Nullable Throwable cause) {
super(message, cause);
this.traceId = traceId;
diff --git
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
index f6c03430f5..93efeb3439 100644
---
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
+++
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
@@ -94,6 +94,7 @@ import org.apache.ignite.internal.hlc.HybridClock;
import org.apache.ignite.internal.hlc.HybridTimestamp;
import org.apache.ignite.internal.jdbc.proto.JdbcQueryCursorHandler;
import org.apache.ignite.internal.jdbc.proto.JdbcQueryEventHandler;
+import org.apache.ignite.internal.lang.IgniteExceptionMapperUtil;
import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.logger.Loggers;
@@ -450,7 +451,7 @@ public class ClientInboundMessageHandler extends
ChannelInboundHandlerAdapter im
}
// No need to send internal errors to client.
- Throwable pubErr = ExceptionUtils.unwrapToPublicException(err);
+ Throwable pubErr =
IgniteExceptionMapperUtil.mapToPublicException(ExceptionUtils.unwrapCause(err));
// Class name and message.
packer.packString(pubErr.getClass().getName());
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/ClientUtils.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/ClientUtils.java
index 5304b76e5c..27c4871527 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/ClientUtils.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/ClientUtils.java
@@ -17,22 +17,68 @@
package org.apache.ignite.internal.client;
-import static org.apache.ignite.internal.util.ExceptionUtils.sneakyThrow;
+import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
+import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.apache.ignite.client.ClientOperationType;
import org.apache.ignite.client.IgniteClientConfiguration;
import org.apache.ignite.internal.client.proto.ClientOp;
+import org.apache.ignite.internal.lang.IgniteExceptionMapperUtil;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.logger.Loggers;
import org.apache.ignite.internal.util.ExceptionUtils;
+import org.apache.ignite.lang.IgniteCheckedException;
+import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.lang.LoggerFactory;
+import org.apache.ignite.lang.TraceableException;
/**
* Client utilities.
*/
public class ClientUtils {
+ /**
+ * Wraps an exception in an IgniteException, extracting trace identifier
and error code when the specified exception or one of its
+ * causes is an IgniteException itself.
+ *
+ * @param e Internal exception.
+ * @return Public exception.
+ */
+ public static Throwable ensurePublicException(Throwable e) {
+ Objects.requireNonNull(e);
+
+ e = ExceptionUtils.unwrapCause(e);
+
+ if (e instanceof IgniteException) {
+ return copyExceptionWithCauseIfPossible((IgniteException) e);
+ }
+
+ if (e instanceof IgniteCheckedException) {
+ return copyExceptionWithCauseIfPossible((IgniteCheckedException)
e);
+ }
+
+ e = IgniteExceptionMapperUtil.mapToPublicException(e);
+
+ return new IgniteException(INTERNAL_ERR, e.getMessage(), e);
+ }
+
+ /**
+ * Try to copy exception using ExceptionUtils.copyExceptionWithCause and
return new exception if it was not possible.
+ *
+ * @param e Exception.
+ * @return Properly copied exception or a new error, if exception can not
be copied.
+ */
+ private static <T extends Throwable & TraceableException> Throwable
copyExceptionWithCauseIfPossible(T e) {
+ Throwable copy = ExceptionUtils.copyExceptionWithCause(e.getClass(),
e.traceId(), e.code(), e.getMessage(), e);
+ if (copy != null) {
+ return copy;
+ }
+
+ return new IgniteException(INTERNAL_ERR, "Public Ignite
exception-derived class does not have required constructor: "
+ + e.getClass().getName(), e);
+ }
+
/**
* Waits for async operation completion.
*
@@ -46,9 +92,9 @@ public class ClientUtils {
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Restore interrupt flag.
- throw sneakyThrow(ExceptionUtils.unwrapToPublicException(e));
+ throw ExceptionUtils.sneakyThrow(ensurePublicException(e));
} catch (ExecutionException e) {
- throw sneakyThrow(ExceptionUtils.unwrapToPublicException(e));
+ throw ExceptionUtils.sneakyThrow(ensurePublicException(e));
}
}
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
index 36ca04d3ef..119a49cab0 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
@@ -58,7 +58,6 @@ import org.apache.ignite.internal.client.proto.ResponseFlags;
import org.apache.ignite.internal.client.proto.ServerMessageType;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.tostring.S;
-import org.apache.ignite.internal.util.ExceptionUtils;
import org.apache.ignite.lang.ErrorGroups.Table;
import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.network.NetworkAddress;
@@ -326,7 +325,7 @@ class TcpClientChannel implements ClientChannel,
ClientMessageHandler, ClientCon
metrics.requestsActiveDecrement();
- throw sneakyThrow(ExceptionUtils.unwrapToPublicException(t));
+ throw sneakyThrow(ClientUtils.ensurePublicException(t));
}
}
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
index 1b23016fcd..18272ca3d3 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
@@ -17,7 +17,6 @@
package org.apache.ignite.internal.client.compute;
-import static org.apache.ignite.internal.util.ExceptionUtils.sneakyThrow;
import static org.apache.ignite.lang.ErrorGroups.Client.TABLE_ID_NOT_FOUND_ERR;
import java.util.HashMap;
@@ -32,6 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import org.apache.ignite.compute.DeploymentUnit;
import org.apache.ignite.compute.IgniteCompute;
+import org.apache.ignite.internal.client.ClientUtils;
import org.apache.ignite.internal.client.ReliableChannel;
import org.apache.ignite.internal.client.proto.ClientMessagePacker;
import org.apache.ignite.internal.client.proto.ClientOp;
@@ -103,7 +103,7 @@ public class ClientCompute implements IgniteCompute {
try {
return this.<R>executeAsync(nodes, units, jobClassName,
args).join();
} catch (CompletionException e) {
- throw sneakyThrow(ExceptionUtils.unwrapToPublicException(e));
+ throw
ExceptionUtils.sneakyThrow(ClientUtils.ensurePublicException(e));
}
}
@@ -169,7 +169,7 @@ public class ClientCompute implements IgniteCompute {
try {
return this.<R>executeColocatedAsync(tableName, key, units,
jobClassName, args).join();
} catch (CompletionException e) {
- throw sneakyThrow(ExceptionUtils.unwrapToPublicException(e));
+ throw
ExceptionUtils.sneakyThrow(ClientUtils.ensurePublicException(e));
}
}
@@ -186,7 +186,7 @@ public class ClientCompute implements IgniteCompute {
try {
return this.<K, R>executeColocatedAsync(tableName, key, keyMapper,
units, jobClassName, args).join();
} catch (CompletionException e) {
- throw sneakyThrow(ExceptionUtils.unwrapToPublicException(e));
+ throw
ExceptionUtils.sneakyThrow(ClientUtils.ensurePublicException(e));
}
}
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueBinaryViewTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueBinaryViewTest.java
index f170db1202..70384fdd32 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueBinaryViewTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueBinaryViewTest.java
@@ -17,6 +17,10 @@
package org.apache.ignite.client;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasToString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -24,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -174,6 +179,7 @@ public class ClientKeyValueBinaryViewTest extends
AbstractClientTableTest {
var ex = assertThrows(IgniteException.class, () ->
kvView.contains(null, Tuple.create()));
assertTrue(ex.getMessage().contains("Missed key column: ID"),
ex.getMessage());
+ assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("ClientKeyValueBinaryView"))));
}
@Test
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
index 4b53e67b6a..b0fa0cd1bb 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientKeyValueViewTest.java
@@ -19,7 +19,9 @@ package org.apache.ignite.client;
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasToString;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -31,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.temporal.ChronoUnit;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.List;
@@ -100,6 +103,8 @@ public class ClientKeyValueViewTest extends
AbstractClientTableTest {
IgniteException e = assertThrows(IgniteException.class, () ->
pojoView.get(null, key));
assertEquals("Failed to deserialize server response: No mapped object
field found for column 'ZBOOLEAN'", e.getMessage());
+ assertThat(Arrays.asList(e.getStackTrace()),
anyOf(hasToString(containsString("ClientKeyValueView"))));
+
}
@Test
@@ -200,6 +205,7 @@ public class ClientKeyValueViewTest extends
AbstractClientTableTest {
IgniteException e = assertThrows(IgniteException.class, () ->
kvView.get(null, new NamePojo()));
assertThat(e.getMessage(), containsString("No mapped object field
found for column 'ID'"));
+ assertThat(Arrays.asList(e.getStackTrace()),
anyOf(hasToString(containsString("ClientKeyValueView"))));
}
@Test
@@ -485,5 +491,6 @@ public class ClientKeyValueViewTest extends
AbstractClientTableTest {
var ex = assertThrows(IgniteException.class, () -> pojoView.put(null,
1, pojo));
assertTrue(ex.getMessage().contains("null was passed, but column is
not nullable"), ex.getMessage());
+ assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("ClientKeyValueView"))));
}
}
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
index b5c3e1007f..2a906efd40 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
@@ -19,7 +19,9 @@ package org.apache.ignite.client;
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasToString;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -31,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.temporal.ChronoUnit;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.List;
@@ -104,6 +107,7 @@ public class ClientRecordViewTest extends
AbstractClientTableTest {
// This POJO does not have fields for all table columns, which is not
allowed (to avoid unexpected data loss).
IgniteException ex = assertThrows(IgniteException.class, () ->
pojoView.get(null, key));
assertEquals("Failed to deserialize server response: No mapped object
field found for column 'ZBOOLEAN'", ex.getMessage());
+ assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("ClientRecordView"))));
}
@Test
@@ -195,6 +199,7 @@ public class ClientRecordViewTest extends
AbstractClientTableTest {
IgniteException e = assertThrows(IgniteException.class, () ->
recordView.get(null, new NamePojo()));
assertThat(e.getMessage(), containsString("No mapped object field
found for column 'ID'"));
+ assertThat(Arrays.asList(e.getStackTrace()),
anyOf(hasToString(containsString("ClientRecordView"))));
}
@Test
@@ -511,5 +516,6 @@ public class ClientRecordViewTest extends
AbstractClientTableTest {
var ex = assertThrows(IgniteException.class, () ->
pojoView.upsert(null, pojo));
assertTrue(ex.getMessage().contains("null was passed, but column is
not nullable"), ex.getMessage());
+ assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("ClientRecordView"))));
}
}
diff --git
a/modules/client/src/test/java/org/apache/ignite/internal/client/ClientUtilsTest.java
b/modules/client/src/test/java/org/apache/ignite/internal/client/ClientUtilsTest.java
new file mode 100644
index 0000000000..eb41308fb2
--- /dev/null
+++
b/modules/client/src/test/java/org/apache/ignite/internal/client/ClientUtilsTest.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client;
+
+import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasToString;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import org.apache.ignite.lang.IgniteCheckedException;
+import org.apache.ignite.lang.IgniteException;
+import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Future utils test.
+ */
+public class ClientUtilsTest {
+ @Test
+ public void testEnsurePublicExceptionIgniteException() {
+ IgniteException ex = assertThrows(IgniteException.class,
ClientUtilsTest::throwIgniteException);
+
+ Throwable resEx = checkableTestMethod(ex);
+
+ assertTrue(resEx instanceof IgniteException);
+ assertEquals("Test ignite exception", resEx.getMessage());
+ assertEquals(ex.getMessage(), resEx.getMessage());
+ assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("throwIgniteException"))));
+ assertThat(Arrays.asList(resEx.getStackTrace()),
anyOf(hasToString(containsString("checkableTestMethod"))));
+ assertSame(ex.getClass(), resEx.getCause().getClass());
+ }
+
+ @Test
+ public void testEnsurePublicExceptionIgniteCheckedException() {
+ IgniteCheckedException ex = assertThrows(IgniteCheckedException.class,
ClientUtilsTest::throwIgniteCheckedException);
+
+ Throwable resEx = checkableTestMethod(ex);
+
+ assertTrue(resEx instanceof IgniteCheckedException);
+ assertEquals("Test checked exception", resEx.getMessage());
+ assertEquals(ex.getMessage(), resEx.getMessage());
+ assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("throwIgniteCheckedException"))));
+ assertThat(Arrays.asList(resEx.getStackTrace()),
anyOf(hasToString(containsString("checkableTestMethod"))));
+ assertSame(ex.getClass(), resEx.getCause().getClass());
+ }
+
+ @Test
+ public void testEnsurePublicExceptionRuntimeException() {
+ RuntimeException ex = assertThrows(RuntimeException.class,
ClientUtilsTest::throwRuntimeException);
+
+ Throwable resEx = checkableTestMethod(ex);
+
+ assertTrue(resEx instanceof IgniteException);
+ assertEquals("Test runtime exception", resEx.getMessage());
+ assertEquals(ex.getMessage(), resEx.getMessage());
+ assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("throwRuntimeException"))));
+ assertThat(Arrays.asList(resEx.getStackTrace()),
anyOf(hasToString(containsString("checkableTestMethod"))));
+ assertSame(IgniteException.class, resEx.getCause().getClass());
+ assertSame(ex.getClass(), resEx.getCause().getCause().getClass());
+ }
+
+ @Test
+ public void testEnsurePublicExceptionInvalidIgniteException() {
+ InvalidIgniteException ex = assertThrows(InvalidIgniteException.class,
ClientUtilsTest::throwInvalidIgniteException);
+
+ Throwable resEx = checkableTestMethod(ex);
+
+ assertTrue(resEx instanceof IgniteException);
+ assertThat(resEx.getMessage(), containsString("Public Ignite
exception-derived class does not have required constructor"));
+ assertThat(Arrays.asList(ex.getStackTrace()),
anyOf(hasToString(containsString("throwInvalidIgniteException"))));
+ assertThat(Arrays.asList(resEx.getStackTrace()),
anyOf(hasToString(containsString("checkableTestMethod"))));
+ assertSame(InvalidIgniteException.class, resEx.getCause().getClass());
+ assertSame(ex.getClass(), resEx.getCause().getClass());
+ }
+
+ /**
+ * Method that should present in resulting stack trace.
+ */
+ private static Throwable checkableTestMethod(Throwable ex) {
+ return ClientUtils.ensurePublicException(ex);
+ }
+
+ /**
+ * Un-constructable IgniteException.
+ */
+ private static class InvalidIgniteException extends IgniteException {
+ InvalidIgniteException(int code, String message, @Nullable Throwable
cause) {
+ super(code, message, cause);
+ }
+ }
+
+ private static void throwInvalidIgniteException() {
+ throw new InvalidIgniteException(INTERNAL_ERR, "Test invalid ignite
exception", null);
+ }
+
+ private static void throwIgniteException() {
+ throw new IgniteException(INTERNAL_ERR, "Test ignite exception", null);
+ }
+
+ private static void throwIgniteCheckedException() throws
IgniteCheckedException {
+ throw new IgniteCheckedException(INTERNAL_ERR, "Test checked
exception", null);
+ }
+
+ private static void throwRuntimeException() {
+ throw new RuntimeException("Test runtime exception", null);
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/util/ExceptionUtils.java
b/modules/core/src/main/java/org/apache/ignite/internal/util/ExceptionUtils.java
index 6cf71b7cd2..acef8dc60c 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/util/ExceptionUtils.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/util/ExceptionUtils.java
@@ -38,7 +38,6 @@ import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
-import org.apache.ignite.internal.lang.IgniteExceptionMapperUtil;
import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
import org.apache.ignite.internal.lang.IgniteInternalException;
import org.apache.ignite.internal.lang.IgniteQuadFunction;
@@ -347,16 +346,6 @@ public final class ExceptionUtils {
return e;
}
- /**
- * Unwraps exception cause from wrappers like CompletionException and
ExecutionException and converts it to public exception.
- *
- * @param err Exception.
- * @return Public exception.
- */
- public static Throwable unwrapToPublicException(Throwable err) {
- return
IgniteExceptionMapperUtil.mapToPublicException(unwrapCause(err));
- }
-
/**
* Creates a new exception, which type is defined by the provided {@code
supplier}, with the specified {@code t} as a cause.
* In the case when the provided cause {@code t} is an instance of {@link
TraceableException},
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientComputeTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientComputeTest.java
index c1f596d995..3f10fa8899 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientComputeTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientComputeTest.java
@@ -171,8 +171,7 @@ public class ItThinClientComputeTest extends
ItAbstractThinClientTest {
IgniteException.class,
() -> client().compute().<String>execute(Set.of(node(0)),
List.of(), IgniteExceptionJob.class.getName()));
- // TODO IGNITE-20858: Once user errors are handled properly, make
sure the cause is checked
- cause = ex;
+ cause = (IgniteException) ex.getCause();
}
assertThat(cause.getMessage(), containsString("Custom job error"));
@@ -198,8 +197,7 @@ public class ItThinClientComputeTest extends
ItAbstractThinClientTest {
IgniteException.class,
() -> client().compute().<String>execute(Set.of(node(0)),
List.of(), ExceptionJob.class.getName()));
- // TODO IGNITE-20858: Once user errors are handled properly, make
sure the cause is checked
- cause = ex;
+ cause = (IgniteException) ex.getCause();
}
// TODO IGNITE-20858: Once user errors are handled properly, make sure
the cause is ArithmeticException
@@ -225,8 +223,7 @@ public class ItThinClientComputeTest extends
ItAbstractThinClientTest {
IgniteException.class,
() -> client().compute().execute(Set.of(node(1)),
List.of(), ExceptionJob.class.getName()));
- // TODO IGNITE-20858: Once user errors are handled properly, make
sure the cause is checked
- cause = ex;
+ cause = (IgniteException) ex.getCause();
}
// TODO IGNITE-20858: Once user errors are handled properly, make sure
the cause is ArithmeticException