[ https://issues.apache.org/jira/browse/IGNITE-19535?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17731936#comment-17731936 ]
Vyacheslav Koptilin commented on IGNITE-19535: ---------------------------------------------- Hello [~ibessonov] , [~sanpwc] , Could you please take a look at the patch [https://github.com/apache/ignite-3/pull/2178] ? > Removing the constraint that all public exceptions should implement the > mandatory constructor Exception(UUID, int, String, Throwable) > ------------------------------------------------------------------------------------------------------------------------------------- > > Key: IGNITE-19535 > URL: https://issues.apache.org/jira/browse/IGNITE-19535 > Project: Ignite > Issue Type: Improvement > Reporter: Vyacheslav Koptilin > Assignee: Vyacheslav Koptilin > Priority: Major > Labels: iep-84, ignite-3 > Fix For: 3.0.0-beta2 > > Time Spent: 10m > Remaining Estimate: 0h > > For now, it is required that all public exceptions have to have a constructor > which accepts trace identifier, error code, error message, and cause: > {code:java} > InternalException(UUID traceId, int code, String message, Throwable cause) > {code} > Initially, this requirement came from the following considerations: if you > trying to implement sync API over async: > {code:java} > /** > * Returns a future that can be used to extract a result of async computation. > * This future can be completed with a {@code CustomException} if computation > failed. > */ > public CompletableFuture<Result> asyncApiCall() {...} > /** > * Returns a result of sync computation. > * @throws CustomException if computation failed. > */ > public Result syncApiCall() throws CustomException { > try { > return asyncApiCall().join(); > catch (CompletionException e) { > throw e.getCause(); // simple solution that is not correct > } > }{code} > Obviously, the user does not expect that `syncApiCall` can throw > CompletionException instead of CustomException. The simplest option is > throwing `e.getCause()`, but in that case, the end-user will lose a part of > the stack trace representing CompletionException (path to the syncApiCall), > and he/she will only stay with the `remote` stack trace. So, the > implementation should create a new exception that has the same type as > `e.getCause` and should throw it. > One of the possible solutions is to write a util method that iterates over > all predefined constructor signatures, starting from the most specific > signature, and tries to create the required type of the exception: > {noformat} > Exception(UUID traceId, int code, String message, Throwable cause) > Exception(UUID traceId, int code, String message) > Exception(UUID traceId, int code, Throwable cause) > Exception(int code, String message, Throwable cause) > Exception(int code, String message) > Exception(int code, Throwable cause) > Exception(UUID traceId, int code) > Exception(String msg, Throwable cause) > Exception(int code) > Exception(String msg) > Exception(Throwable cause) > Exception(){noformat} > In that case, our example can be modified as follows: > {code:java} > /** > * Returns a result of sync computation. > * @throws CustomException if computation failed. > */ > public Result syncApiCall() throws CustomException { > try { > return asyncApiCall().join(); > catch (CompletionException e) { > throw sneakyThrow(createCopyExceptionWithCause(e)); // here we will > throw a new exception with the same type > } > } {code} > > It seems to me, that this approach should resolve the vast majority of use > cases. Unfortunately, both solutions fail when the CustomException does not > have any of mentioned constructor signatures: > {noformat} > public class CustomException extends IgniteException { > int[] partitionIds; > public CustomException(int[] patrIds) { > super(SPECIFICE_ERR, "Failed to map an operation for partitions > [partIds=" + partIds + ']); > } > }{noformat} > Such cases should be handled differently. This case will be addressed by a > separate ticket. -- This message was sent by Atlassian Jira (v8.20.10#820010)