Skip to content

Commit 168e875

Browse files
Non retryable errors for activities course port (#4046)
* port from errors course * turning nonretryable errors into sentence form * Update docs/encyclopedia/retry-policies.mdx Co-authored-by: Milecia McG <47196133+flippedcoder@users.noreply.github.com> * Format ApplicationError raising example in Python * Format Java example for non-retryable error Fix formatting of non-retryable error example in Java. * Update docs/encyclopedia/retry-policies.mdx Co-authored-by: Milecia McG <47196133+flippedcoder@users.noreply.github.com> --------- Co-authored-by: Milecia McG <47196133+flippedcoder@users.noreply.github.com>
1 parent f25508e commit 168e875

1 file changed

Lines changed: 149 additions & 6 deletions

File tree

docs/encyclopedia/retry-policies.mdx

Lines changed: 149 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ tags:
1313
---
1414

1515
import { CaptionedImage, RelatedReadContainer, RelatedReadItem } from '@site/src/components';
16+
import Tabs from '@theme/Tabs';
17+
import TabItem from '@theme/TabItem';
1618

1719
A Retry Policy is a collection of settings that tells Temporal how and when to try again after something fails in a Workflow Execution or Activity Task Execution.
1820

@@ -132,13 +134,154 @@ Non-Retryable Errors = []
132134
- **Use case:** Use this attribute to ensure that retries do not continue indefinitely.
133135
In most cases, we recommend using the Workflow Execution Timeout for [Workflows](/workflows) or the Schedule-To-Close Timeout for Activities to limit the total duration of retries, rather than using this attribute.
134136

135-
### Non-Retryable Errors
137+
### Non-Retryable Errors {#non-retryable-errors}
136138

137-
- **Description:** Specifies errors that shouldn't be retried.
138-
- **Default is none.**
139-
- Errors are matched against the `type` field of the [Application Failure](/references/failures#application-failure).
140-
- If one of those errors occurs, a retry does not occur.
141-
- **Use case:** If you know of errors that should not trigger a retry, you can specify that, if they occur, the execution is not retried.
139+
Non-Retryable Errors specify errors that shouldn't be retried.
140+
By default, none are specified.
141+
Errors are matched against the `type` field of the [Application Failure](/references/failures#application-failure).
142+
If one of those errors occurs, a retry does not occur.
143+
If you know of errors that should not trigger a retry, you can specify that and if they occur, the execution is not retried.
144+
145+
#### Non-Retryable Errors for Activities
146+
147+
When writing software applications, you will encounter three types of failures: transient, intermittent, and permanent.
148+
While transient and intermittent failures may resolve themselves upon retrying without further intervention, permanent failures will not.
149+
Permanent failures, by definition, require you to make some change to your logic or your input.
150+
Therefore, it is better to surface them than to retry them.
151+
152+
Non-Retryable Errors are errors that will not be retried, regardless of a Retry Policy.
153+
154+
<Tabs groupId="sdk-language" queryString>
155+
<TabItem value="ruby" label="Ruby">
156+
157+
To raise a non-retryable error, specify the `non_retryable` flag when raising an `ApplicationError`:
158+
159+
```ruby
160+
raise Temporalio::Error::ApplicationError.new(
161+
"Invalid credit card number: #{credit_card_number}",
162+
type: 'InvalidChargeAmount',
163+
non_retryable: true
164+
)
165+
```
166+
167+
This will designate the `ApplicationError` as non-retryable.
168+
169+
</TabItem>
170+
<TabItem value="python" label="Python">
171+
172+
To raise a non-retryable error, specify the `non_retryable` flag when raising an `ApplicationError`:
173+
174+
```python
175+
raise ApplicationError(
176+
f"Invalid credit card number: {credit_card_number}",
177+
type="InvalidChargeAmount",
178+
non_retryable=True,
179+
)
180+
```
181+
182+
This will designate the `ApplicationError` as non-retryable.
183+
184+
</TabItem>
185+
<TabItem value="typescript" label="TypeScript">
186+
187+
To throw a non-retryable error, add `nonRetryable: true` to `ApplicationFailure.create({})`:
188+
189+
```typescript
190+
throw ApplicationFailure.create({
191+
message: `Invalid charge amount: ${chargeAmount} (must be above zero)`,
192+
details: [chargeAmount],
193+
nonRetryable: true
194+
});
195+
```
196+
197+
This will designate the Error as non-retryable.
198+
199+
</TabItem>
200+
<TabItem value="java" label="Java">
201+
202+
To throw a non-retryable error, use the `newNonRetryableFailure` method:
203+
204+
```java
205+
throw ApplicationFailure.newNonRetryableFailure(
206+
"Invalid credit card number: " + creditCardNumber,
207+
InvalidChargeAmountException.class.getName()
208+
);
209+
```
210+
211+
212+
This will designate the `ApplicationFailure` as non-retryable.
213+
214+
</TabItem>
215+
<TabItem value="go" label="Go">
216+
217+
To return a non-retryable error, replace your call to `NewApplicationError()` with `NewNonRetryableApplicationError()`:
218+
219+
```go
220+
temporal.NewNonRetryableApplicationError("Credit Card Charge Error", "CreditCardError", nil, nil)
221+
```
222+
223+
This will designate the Error as non-retryable.
224+
225+
</TabItem>
226+
<TabItem value="dotnet" label=".NET">
227+
228+
To throw a non-retryable error, specify the `nonRetryable` flag when throwing an `ApplicationFailureException`:
229+
230+
```csharp
231+
var attempt = ActivityExecutionContext.Current.Info.Attempt;
232+
233+
throw new ApplicationFailureException(
234+
$"Something bad happened on attempt {attempt}",
235+
errorType: "my_failure_type",
236+
nonRetryable: true
237+
);
238+
```
239+
240+
This will designate the `ApplicationFailureException` as non-retryable.
241+
242+
</TabItem>
243+
</Tabs>
244+
245+
Use non-retryable errors in your code sparingly.
246+
247+
<Tabs groupId="sdk-language" queryString>
248+
<TabItem value="ruby" label="Ruby">
249+
250+
If you do not specify the failure as non-retryable within the definition, you can always mark that error type as non-retryable in your Activity's Retry Policy, but an `ApplicationError` with the `non_retryable` keyword argument set to `true` will always be non-retryable.
251+
252+
</TabItem>
253+
<TabItem value="python" label="Python">
254+
255+
If you do not specify the failure as non-retryable within the definition, you can always mark that error type as non-retryable in your Activity's Retry Policy, but an `ApplicationError` with the `non_retryable` keyword argument set to `True` will always be non-retryable.
256+
257+
</TabItem>
258+
<TabItem value="typescript" label="TypeScript">
259+
260+
If you do not specify the failure as non-retryable within the definition, you can always mark that error type as non-retryable in your Activity's Retry Policy, but an error with `nonRetryable: true` set will always be non-retryable.
261+
262+
</TabItem>
263+
<TabItem value="java" label="Java">
264+
265+
If you throw a regular `newFailure()`, you can always mark that error _type_ as non-retryable in your Activity's Retry Policy, but a `newNonRetryableFailure()` will always be non-retryable.
266+
267+
</TabItem>
268+
<TabItem value="go" label="Go">
269+
270+
If you return a regular `NewApplicationError()`, you can always mark that error _type_ as non-retryable in your Activity's Retry Policy, but a `NewNonRetryableApplicationError()` will always be non-retryable.
271+
272+
</TabItem>
273+
<TabItem value="dotnet" label=".NET">
274+
275+
If you do not specify the failure as non-retryable within the definition, you can always mark that error type as non-retryable in your Activity's Retry Policy, but an `ApplicationFailureException` with the `nonRetryable` parameter set to `true` will always be non-retryable.
276+
277+
</TabItem>
278+
</Tabs>
279+
280+
For example, checking for bad input data is a reasonable time to use a non-retryable error.
281+
If the Activity cannot proceed with the input it has, that error should be surfaced immediately so that the input can be corrected on the next attempt.
282+
283+
If responsibility for your application is distributed across multiple maintainers, or if you are developing a library to integrate into somebody else's application, you can think of the decision to hardcode non-retryable errors as following a "caller vs. implementer" dichotomy.
284+
Anyone who is calling your Activity would be able to make decisions about their Retry Policy, but only the implementer can decide whether an error should never be retryable out of the box.
142285

143286
## Retry interval
144287

0 commit comments

Comments
 (0)