Questions around activity errors, retry, and more complex error handling scenarios

Hi folks-- questions about activity errors and retry – I’m using the Go SDK but I think the questions apply generally

  • If I use Temporal’s retry policies for the activity I can set a list of string types that are not retryable. I could also raise temporal.NewNonRetryableApplicationError() which is always non-retryable, regardless of the retry policy? Is this correct?
  • If the activity will be retried per the policy, does the activity completion future still fire? Within the future, can I tell if the activity is being retried or not? or if it’s already completed? Do I get a different error if the activity has truly, finally failed and is out of retries?
  • This example shows error handling in the workflow future-- for example what is done for CustomErrTypeB – but this error handling is in addition to any retry that the retry policy is already doing, correct? Is the retry happening concurrently or does it wait for the future to return? If so, can a retry be canceled from within the future?
  • This documentation seems to be incorrect or out of date. I can’t find any such thing as CustomError or GenericError in the Go SDK
  • Are there best practices or examples for manually handling retries for more complicated scenarios than what RetryPolicy supports?
  • If I use Temporal’s retry policies for the activity I can set a list of string types that are not retryable. I could also raise temporal.NewNonRetryableApplicationError() which is always non-retryable, regardless of the retry policy? Is this correct?

This is correct.

  • If the activity will be retried per the policy, does the activity completion future still fire? Within the future, can I tell if the activity is being retried or not? or if it’s already completed? Do I get a different error if the activity has truly, finally failed and is out of retries?

The activity completion future will fire only when the activity completes or fails after all the retries are exhausted. Workflow is not notified about the activity progress while it is being retried. When activity is out of retries it gets the last error returned. It also knows what caused the failure through RetryState enum which is included in the error.

  • This example shows error handling in the workflow future-- for example what is done for CustomErrTypeB – but this error handling is in addition to any retry that the retry policy is already doing, correct? Is the retry happening concurrently or does it wait for the future to return? If so, can a retry be canceled from within the future?

Yes, any error handling inside the workflow code happens after the retry policy finished executing. I’m not sure which example you referenced, so not sure what your question about concurrency means.

Activity execution can be canceled by canceling the context passed to ExecuteActivity call. If activity is waiting for the next retry it is canceled immediately and its future is set to the appropriate error.

  • This documentation seems to be incorrect or out of date. I can’t find any such thing as CustomError or GenericError in the Go SDK.

Thanks for pointing this out. We are going to fix this. Use ApplicationError instead.

  • Are there best practices or examples for manually handling retries for more complicated scenarios than what RetryPolicy supports?

Use NewNonRetryableApplicationError to create non retryable errors if the logic of deciding if an error is non retriable should be located in an activity.

Sometimes a whole part of a workflow should be retried on failure. In these cases a workflow has to manage the retry.

1 Like

Thanks for your thorough reply @maxim ! I revised my first post to correctly link the example I referenced. The key part I was missing was that the activity future is not called until after all retries are exhausted. I would suggest adding it to the documentation on error handling and retries. Thanks for clearing that up!

Hi Maxim. Can the retry event be triggered for Activity only if there is any exception thrown from the activity method. Or is there any other way to trigger retry for an activity. Thanks

Hi Maxim. Can the retry event be triggered for Activity only if there is any exception thrown from the activity method? Or is there any other way to trigger retry for an activity? Thanks

@Faizan_Kamal Would you explain what is your need? Currently, the service retries only failed activities. And to fail an activity has to throw an exception (or return an error in Go).

Actually in our case, activities are hitting external rest end point which is returning the response along with status code. So we wanted to handle retry based on the status.

As per current implementation of Temporal, we are checking the status and based on that we are throwing exception explicitly.

In this case, you can throw an ApplicationFailure which can be either retryable or not.

When activity is out of retries it gets the last error returned. It also knows what caused the failure through RetryState enum which is included in the error.

RetryState looks like it is an unexported member of ActivityError in the GoSDK. Is there another way to access this information when handling the error from the workflow?

Good point. Would you file an issue to add public accessors to this and other error fields?

Thanks - filed Add accessors for ActivityError fields · Issue #496 · temporalio/sdk-go · GitHub