What should the java equivalent be here? How do we distinguish errors in an activity that result in the activity being retried, Vs an idempotency error which results in the workflow continuing to the next step? How would we test that in some form of integration test to see the different behaviour?
At the moment i’ve no way to trigger a replay of an activity to validate that idempotency handling works.
in your workflow code then you can handle ActivityFailure and check its cause to see type, for example:
try {
activities.createUser(User user);
} catch (ActivityFailure activityFailure) {
if (activityFailure.getCause() instanceof ApplicationFailure) {
ApplicationFailure af = (ApplicationFailure) activityFailure.getCause();
// af.getMessage();
// af.getType(); --> would be UserAlreadyExistsException
} else if (activityFailure.getCause() instanceof TimeoutFailure) {
TimeoutFailure tf = (TimeoutFailure) activityFailure.getCause();
// tf.getTimeoutType(); -- can be schedule_to_start/schedule_to_close
}
}
In case of a timeout, meaning activity timed out on last attempt, means your code maybe never executed, so maybe best to invoke activity again which would check if it was actually ever created.
Alternatively you could from activity code throw a non-retryable application failure with cause:
Thanks tihomir, very clear. I think what had confused me was how replay would handle activity invocation, i.e. when a workflow is replayed i was worried that it would invoke the activities that had already run, but as i understand it, it will not do that. It will use the stored history from the activities and get the workflow back to where it was running.
I guess the idempotency use case is more focused on activity retries rather than a full workflow replay?