[ 
https://issues.apache.org/jira/browse/IGNITE-19535?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17732951#comment-17732951
 ] 

Alexander Lapin commented on IGNITE-19535:
------------------------------------------

[~slava.koptilin] LGTM from my side.

> 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: 50m
>  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 
> are trying to implement sync API over async then the code may look as follows:
> {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)

Reply via email to