Handle exceptions in Promise

I want to handle the exceptions thrown from an activity, catch it and send it to a slack channel.

 promises.add(Async.function(() -> {
     activity.method1()
     activity.method2()
     return null;
}
Promise.allOf(promises).get();

How could I achieve this?

@Anjula_Paulus

As you have the code now, if activity method1 fails method2 is not gonna be executed, is that what you want?

Antonio

@antonio.perez Yes and I want to catch the exception and notify to a slack channel about the error. It could be wither method1 or method2 that is failing. I am using Activity.wrap to wrap my custom Exception which extends to ResponseStatusException. But the Exception is not captured when invoking all the activities at Promise.allOf(promises).get();

I would iterate over promises list and call get on each promise separately:

for (Promise p: promises) {
   try {
      p.get();
   } catch (...) {
      // send to slack
   } 
}

If I am to use throw Activity.wrap(new CustomException("simulated")); would it be considered as an activity failure ?

Any method from Activity class can be used only by an activity implementation.

I don’t understand what you mean by “considered”. The Promise.get() rethrows the original exception that was thrown from the Async.function.

Activity Code:

        try {
            return something();
        } catch (CustomException | IOException e) {
            throw Activity.wrap(new Exception(e.getMessage()));
        }

Workflow Code:

for (Promise<Void> promise : promises) {
            try {
                promise.get();
            } catch (Exception e) {
                log.error(((ApplicationFailure) e.getCause()).getOriginalMessage());
                sendSlackMessage(((ApplicationFailure) e.getCause()).getOriginalMessage());
            }
        }

The activity seems to be retrying but I cannot see that the catch block logic being executed. There are two activity methods executed sequentially. The first activity is throwing the checked exception and keeps on retrying. Is there something that I am missing here.

Logs:

2023-07-28T20:20:33.295Z WARN 1 — [ce=“default”: 6] tivityTaskExecutors$ActivityTaskExecutor : Activity failure. ActivityId=a1e6e464-1348-3204-8834-2b1fc54fe42a, activityType=Method1, attempt=7
java.lang.Exception: java.lang.IllegalArgumentException:

By default, all activity failures are retried. You can either disable retries for specific error types by including them into RetryOptions.doNot retry list or by explicitly throwing an exception created through ApplicationFailure.newNonRetryableFailure.

I would change your error handling to:

       try {
            return something();
        } catch (CustomException | IOException e) {
            throw Activity.wrap(e);
        }

and add class names of CustomException and IOException to doNotRetryList. Note that any Java exception is converted to an ApplicationFailure exception before being returned to the workflow.

Or

       try {
            return something();
        } catch (CustomException | IOException e) {
            throw ApplicationFailure.newNonRetryableFailure(e.getMessage(), e.getClass().getName());
        }

Thanks alot @maxim