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

**URL:** <https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016>\
**Category:** Community Support\
**Tags:** go-sdk, retries, error-handling\
**Created:** [April 27, 2021, 11:24pm UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016 "2021-04-27T23:24:45Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![aocole](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/aocole/32/747_2.png) [@aocole](https://community.temporal.io/u/aocole)\
**Post date:** [April 27, 2021, 11:24pm UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/1 "2021-04-27T23:24:45Z")

</div>

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](https://github.com/temporalio/sdk-go/blob/master/temporal/error.go) 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](https://pkg.go.dev/go.temporal.io/sdk/workflow#hdr-Error_Handling) 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?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [April 28, 2021, 1:03am UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/2 "2021-04-28T01:03:38Z")

</div>

> - 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](https://github.com/temporalio/api/blob/4c2f6a281fa3fde8b0a24447de3e0d0f47d230b4/temporal/api/enums/v1/workflow.proto#L89) 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](https://github.com/temporalio/sdk-go/blob/a39bbe82b2bab1281d24d7f18a93a9813e0e622b/temporal/error.go#L171) 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.

---

<div class="post-metadata">

**Author:** ![aocole](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/aocole/32/747_2.png) [@aocole](https://community.temporal.io/u/aocole)\
**Post date:** [April 28, 2021, 1:46am UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/3 "2021-04-28T01:46:28Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![Faizan\_Kamal](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@Faizan\_Kamal](https://community.temporal.io/u/Faizan_Kamal)\
**Post date:** [May 18, 2021, 8:33am UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/4 "2021-05-18T08:33:30Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [May 18, 2021, 2:47pm UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/5 "2021-05-18T14:47:21Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Faizan\_Kamal](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@Faizan\_Kamal](https://community.temporal.io/u/Faizan_Kamal)\
**Post date:** [May 18, 2021, 3:06pm UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/6 "2021-05-18T15:06:47Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [May 18, 2021, 3:16pm UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/7 "2021-05-18T15:16:33Z")

</div>

In this case, you can throw an ApplicationFailure which can be either retryable or [not](https://github.com/temporalio/sdk-java/blob/30420212a26283cf7cbe6339512058a3186074e8/temporal-sdk/src/main/java/io/temporal/failure/ApplicationFailure.java#L84).

---

<div class="post-metadata">

**Author:** ![aocole](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/aocole/32/747_2.png) [@aocole](https://community.temporal.io/u/aocole)\
**Post date:** [July 22, 2021, 10:15pm UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/8 "2021-07-22T22:15:23Z")

</div>

> 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?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [July 23, 2021, 12:40am UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/9 "2021-07-23T00:40:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![aocole](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/aocole/32/747_2.png) [@aocole](https://community.temporal.io/u/aocole)\
**Post date:** [July 23, 2021, 10:56pm UTC](https://community.temporal.io/t/questions-around-activity-errors-retry-and-more-complex-error-handling-scenarios/2016/10 "2021-07-23T22:56:19Z")

</div>

Thanks - filed [Add accessors for ActivityError fields · Issue #496 · temporalio/sdk-go · GitHub](https://github.com/temporalio/sdk-go/issues/496)
