[
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)