Skip to content

Commit 4c0df90

Browse files
authored
Merge pull request #201177 from ggailey777/eamon
Update/clean-up retry and errors article
2 parents 3c52fc8 + 825ac9c commit 4c0df90

11 files changed

+332
-414
lines changed

.openpublishing.redirection.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6931,6 +6931,11 @@
69316931
"redirect_url": "/azure/azure-functions/functions-bindings-event-hubs-output",
69326932
"redirect_document_id": false
69336933
},
6934+
{
6935+
"source_path_from_root": "/articles/azure-functions/functions-bindings-errors.md",
6936+
"redirect_url": "/azure/azure-functions/functions-bindings-error-pages",
6937+
"redirect_document_id": false
6938+
},
69346939
{
69356940
"source_path_from_root": "/articles/azure-government/documentation-government-k8.md",
69366941
"redirect_url": "/azure/azure-government",

articles/azure-functions/TOC.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
displayName: encryption, keys, mount, files
181181
- name: Error handling and function retries
182182
href: functions-bindings-error-pages.md
183-
displayName: best practices
183+
displayName: best practices, retry policies
184184
- name: Security
185185
href: security-concepts.md
186186
displayName: best practices
Lines changed: 294 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,318 @@
11
---
22
title: Azure Functions error handling and retry guidance
3-
description: Learn to handle errors and retry events in Azure Functions with links to specific binding errors.
3+
description: Learn to handle errors and retry events in Azure Functions with links to specific binding errors, including information on retry policies.
44

55
ms.topic: conceptual
6-
ms.date: 10/01/2020
6+
ms.date: 06/09/2022
7+
zone_pivot_groups: programming-languages-set-functions-lang-workers
78
---
89

910
# Azure Functions error handling and retries
1011

11-
Handling errors in Azure Functions is important to avoid lost data, missed events, and to monitor the health of your application.
12+
Handling errors in Azure Functions is important to avoid lost data, missed events, and to monitor the health of your application. It's also important to understand the retry behaviors of event-based triggers.
1213

13-
This article describes general strategies for error handling along with links to binding-specific errors.
14+
This article describes general strategies for error handling and the available retry strategies.
15+
16+
> [!IMPORTANT]
17+
> The retry policy support in the runtime for triggers other than Timer and Event Hubs is being removed after this feature becomes generally available (GA). Preview retry policy support for all triggers other than Timer and Event Hubs will be removed in October 2022.
1418
1519
## Handling errors
1620

17-
[!INCLUDE [bindings errors intro](../../includes/functions-bindings-errors-retries.md)]
21+
Errors raised in an Azure Functions can come from any of the following origins:
22+
23+
- Use of built-in Azure Functions [triggers and bindings](functions-triggers-bindings.md).
24+
- Calls to APIs of underlying Azure services.
25+
- Calls to REST endpoints.
26+
- Calls to client libraries, packages, or third-party APIs.
27+
28+
Good error handling practices are important to avoid loss of data or missed messages. This section describes some recommended error handling practices with links to more information.
29+
30+
### Enable Application Insights
31+
32+
Azure Functions integrates with Application Insights to collect error data, performance data, and runtime logs. You should use Application Insights to discover and better understand errors occurring in your function executions. To learn more, see [Monitor Azure Functions](functions-monitoring.md).
33+
34+
### Use structured error handling
35+
36+
Capturing and logging errors is critical to monitoring the health of your application. The top-most level of any function code should include a try/catch block. In the catch block, you can capture and log errors. For information about what errors might be raised by bindings, see [Binding error codes](#binding-error-codes).
37+
38+
### Plan your retry strategy
39+
40+
Several Functions bindings extensions provide built-in support for retries. In addition, the runtime lets you define retry policies for Timer and Event Hubs triggered functions. To learn more, see [Retries](#retries). For triggers that don't provide retry behaviors, you may want to implement your own retry scheme.
41+
42+
### Design for idempotency
43+
44+
The occurrence of errors when processing data can be a problem for your functions, especially when processing messages. You need to consider what happens when the error occurs and how to avoid duplicate processing. To learn more, see [Designing Azure Functions for identical input](functions-idempotent.md).
45+
46+
## Retries
47+
48+
There are two kinds of retries available for your functions: built-in retry behaviors of individual trigger extensions and retry policies. The following table indicates which triggers support retries and where the retry behavior is configured. It also links to more information about errors coming from the underlying services.
49+
50+
| Trigger/binding | Retry source | Configuration |
51+
| ---- | ---- | ----- |
52+
| Azure Cosmos DB | n/a | Not configurable |
53+
| Blob Storage | [Binding extension](functions-bindings-storage-blob-trigger.md#poison-blobs) | [host.json](functions-bindings-storage-queue.md#host-json) |
54+
| Event Grid | [Binding extension](../event-grid/delivery-and-retry.md) | Event subscription |
55+
| Event Hubs | [Retry policies](#retry-policies) | Function-level |
56+
| Queue Storage | [Binding extension](functions-bindings-storage-queue-trigger.md#poison-messages) | [host.json](functions-bindings-storage-queue.md#host-json) |
57+
| RabbitMQ | [Binding extension](functions-bindings-rabbitmq-trigger.md#dead-letter-queues) | [Dead letter queue](https://www.rabbitmq.com/dlx.html) |
58+
| Service Bus | [Binding extension](../service-bus-messaging/service-bus-dead-letter-queues.md) | [Dead letter queue](/service-bus-messaging/service-bus-dead-letter-queues.md#maximum-delivery-count) |
59+
|Timer | [Retry policies](#retry-policies) | Function-level |
60+
61+
### Retry policies
62+
63+
Starting with version 3.x of the Azure Functions runtime, you can define a retry policies for Timer and Event Hubs triggers that are enforced by the Functions runtime. The retry policy tells the runtime to rerun a failed execution until either successful completion occurs or the maximum number of retries is reached.
64+
65+
A retry policy is evaluated when a Timer or Event Hubs triggered function raises an uncaught exception. As a best practice, you should catch all exceptions in your code and rethrow any errors that you want to result in a retry. Event Hubs checkpoints won't be written until the retry policy for the execution has completed. Because of this behavior, progress on the specific partition is paused until the current batch has completed.
66+
67+
#### Retry strategies
68+
69+
There are two retry strategies supported by policy that you can configure:
70+
71+
# [Fixed delay](#tab/fixed-delay)
72+
73+
A specified amount of time is allowed to elapse between each retry.
74+
75+
# [Exponential backoff](#tab/exponential-backoff)
76+
77+
The first retry waits for the minimum delay. On subsequent retries, time is added exponentially to the initial duration for each retry, until the maximum delay is reached. Exponential back-off adds some small randomization to delays to stagger retries in high-throughput scenarios.
78+
79+
---
80+
81+
#### Max retry counts
82+
83+
You can configure the maximum number of times function execution is retried before eventual failure. The current retry count is stored in memory of the instance. It's possible that an instance has a failure between retry attempts. When an instance fails during a retry policy, the retry count is lost. When there are instance failures, the Event Hubs trigger is able to resume processing and retry the batch on a new instance, with the retry count reset to zero. Timer trigger doesn't resume on a new instance. This behavior means that the max retry count is a best effort, and in some rare cases an execution could be retried more than the maximum. For Timer triggers, the retries can be less than the maximum requested.
84+
85+
#### Retry examples
86+
87+
::: zone pivot="programming-language-csharp"
88+
89+
# [In-process](#tab/in-process/fixed-delay)
90+
91+
Retries require NuGet package [Microsoft.Azure.WebJobs](https://www.nuget.org/packages/Microsoft.Azure.WebJobs) >= 3.0.23
92+
93+
```csharp
94+
[FunctionName("EventHubTrigger")]
95+
[FixedDelayRetry(5, "00:00:10")]
96+
public static async Task Run([EventHubTrigger("myHub", Connection = "EventHubConnection")] EventData[] events, ILogger log)
97+
{
98+
// ...
99+
}
100+
```
101+
102+
|Property | Description |
103+
|---------|-------------|
104+
|MaxRetryCount|Required. The maximum number of retries allowed per function execution. `-1` means to retry indefinitely.|
105+
|DelayInterval|The delay that is used between retries. Specify as a string with the format `HH:mm:ss`.|
106+
107+
# [Isolated process](#tab/isolated-process/fixed-delay)
108+
109+
Retry policies aren't yet supported when running in an isolated process.
110+
111+
# [C# Script](#tab/csharp-script/fixed-delay)
112+
113+
Here's the retry policy in the *function.json* file:
114+
115+
```json
116+
{
117+
"disabled": false,
118+
"bindings": [
119+
{
120+
....
121+
}
122+
],
123+
"retry": {
124+
"strategy": "fixedDelay",
125+
"maxRetryCount": 4,
126+
"delayInterval": "00:00:10"
127+
}
128+
}
129+
```
130+
131+
|function.json property | Description |
132+
|---------|-------------|
133+
|strategy|Use `fixedDelay`.|
134+
|maxRetryCount|Required. The maximum number of retries allowed per function execution. `-1` means to retry indefinitely.|
135+
|delayInterval|The delay that is used between retries. Specify as a string with the format `HH:mm:ss`.|
136+
137+
# [In-process](#tab/in-process/exponential-backoff)
138+
139+
Retries require NuGet package [Microsoft.Azure.WebJobs](https://www.nuget.org/packages/Microsoft.Azure.WebJobs) >= 3.0.23
140+
141+
```csharp
142+
[FunctionName("EventHubTrigger")]
143+
[ExponentialBackoffRetry(5, "00:00:04", "00:15:00")]
144+
public static async Task Run([EventHubTrigger("myHub", Connection = "EventHubConnection")] EventData[] events, ILogger log)
145+
{
146+
// ...
147+
}
148+
```
149+
150+
|Property | Description |
151+
|---------|-------------|
152+
|MaxRetryCount|Required. The maximum number of retries allowed per function execution. `-1` means to retry indefinitely.|
153+
|MinimumInterval|The minimum retry delay. Specify as a string with the format `HH:mm:ss`.|
154+
|MaximumInterval|The maximum retry delay. Specify as a string with the format `HH:mm:ss`.|
155+
156+
# [Isolated process](#tab/isolated-process/exponential-backoff)
157+
158+
Retry policies aren't yet supported when running in an isolated process.
159+
160+
# [C# Script](#tab/csharp-script/exponential-backoff)
161+
162+
Here's the retry policy in the *function.json* file:
163+
164+
```json
165+
{
166+
"disabled": false,
167+
"bindings": [
168+
{
169+
....
170+
}
171+
],
172+
"retry": {
173+
"strategy": "exponentialBackoff",
174+
"maxRetryCount": 5,
175+
"minimumInterval": "00:00:10",
176+
"maximumInterval": "00:15:00"
177+
}
178+
}
179+
```
180+
181+
|function.json property | Description |
182+
|---------|-------------|
183+
|strategy|Use `exponentialBackoff`.|
184+
|maxRetryCount|Required. The maximum number of retries allowed per function execution. `-1` means to retry indefinitely.|
185+
|minimumInterval|The minimum retry delay. Specify as a string with the format `HH:mm:ss`.|
186+
|maximumInterval|The maximum retry delay. Specify as a string with the format `HH:mm:ss`.|
187+
188+
---
189+
::: zone-end
190+
::: zone pivot="programming-language-javascript,programming-language-python,programming-language-powershell"
191+
192+
Here's the retry policy in the *function.json* file:
193+
194+
# [Fixed delay](#tab/fixed-delay)
195+
196+
```json
197+
{
198+
"disabled": false,
199+
"bindings": [
200+
{
201+
....
202+
}
203+
],
204+
"retry": {
205+
"strategy": "fixedDelay",
206+
"maxRetryCount": 4,
207+
"delayInterval": "00:00:10"
208+
}
209+
}
210+
```
211+
212+
# [Exponential backoff](#tab/exponential-backoff)
213+
214+
```json
215+
{
216+
"disabled": false,
217+
"bindings": [
218+
{
219+
....
220+
}
221+
],
222+
"retry": {
223+
"strategy": "exponentialBackoff",
224+
"maxRetryCount": 5,
225+
"minimumInterval": "00:00:10",
226+
"maximumInterval": "00:15:00"
227+
}
228+
}
229+
```
230+
231+
---
232+
233+
|function.json property | Description |
234+
|---------|-------------|
235+
|strategy|Required. The retry strategy to use. Valid values are `fixedDelay` or `exponentialBackoff`.|
236+
|maxRetryCount|Required. The maximum number of retries allowed per function execution. `-1` means to retry indefinitely.|
237+
|delayInterval|The delay that is used between retries when using a `fixedDelay` strategy. Specify as a string with the format `HH:mm:ss`.|
238+
|minimumInterval|The minimum retry delay when using an `exponentialBackoff` strategy. Specify as a string with the format `HH:mm:ss`.|
239+
|maximumInterval|The maximum retry delay when using `exponentialBackoff` strategy. Specify as a string with the format `HH:mm:ss`.|
240+
241+
::: zone-end
242+
::: zone pivot="programming-language-python"
243+
244+
Here's a Python sample to use retry context in a function:
245+
246+
```Python
247+
import azure.functions
248+
import logging
249+
250+
251+
def main(mytimer: azure.functions.TimerRequest, context: azure.functions.Context) -> None:
252+
logging.info(f'Current retry count: {context.retry_context.retry_count}')
253+
254+
if context.retry_context.retry_count == context.retry_context.max_retry_count:
255+
logging.info(
256+
f"Max retries of {context.retry_context.max_retry_count} for "
257+
f"function {context.function_name} has been reached")
258+
259+
```
260+
261+
::: zone-end
262+
::: zone pivot="programming-language-java"
263+
264+
# [Fixed delay](#tab/fixed-delay)
265+
266+
```java
267+
@FunctionName("TimerTriggerJava1")
268+
@FixedDelayRetry(maxRetryCount = 4, delayInterval = "00:00:10")
269+
public void run(
270+
@TimerTrigger(name = "timerInfo", schedule = "0 */5 * * * *") String timerInfo,
271+
final ExecutionContext context
272+
) {
273+
context.getLogger().info("Java Timer trigger function executed at: " + LocalDateTime.now());
274+
}
275+
```
276+
277+
# [Exponential backoff](#tab/exponential-backoff)
278+
279+
```java
280+
@FunctionName("TimerTriggerJava1")
281+
@ExponentialBackoffRetry(maxRetryCount = 5 , maximumInterval = "00:15:00", minimumInterval = "00:00:10")
282+
public void run(
283+
@TimerTrigger(name = "timerInfo", schedule = "0 */5 * * * *") String timerInfo,
284+
final ExecutionContext context
285+
) {
286+
context.getLogger().info("Java Timer trigger function executed at: " + LocalDateTime.now());
287+
}
288+
```
289+
290+
|Element | Description |
291+
|---------|-------------|
292+
|maxRetryCount|Required. The maximum number of retries allowed per function execution. `-1` means to retry indefinitely.|
293+
|delayInterval|The delay that is used between retries when using a `fixedDelay` strategy. Specify as a string with the format `HH:mm:ss`.|
294+
|minimumInterval|The minimum retry delay when using an `exponentialBackoff` strategy. Specify as a string with the format `HH:mm:ss`.|
295+
|maximumInterval|The maximum retry delay when using `exponentialBackoff` strategy. Specify as a string with the format `HH:mm:ss`.|
296+
297+
---
298+
299+
::: zone-end
18300

19301
## Binding error codes
20302

21303
When integrating with Azure services, errors may originate from the APIs of the underlying services. Information relating to binding-specific errors is available in the **Exceptions and return codes** section of the following articles:
22304

23-
+ [Azure Cosmos DB](functions-bindings-cosmosdb.md#exceptions-and-return-codes)
24-
305+
+ [Azure Cosmos DB](/rest/api/cosmos-db/http-status-codes-for-cosmosdb)
25306
+ [Blob storage](functions-bindings-storage-blob-output.md#exceptions-and-return-codes)
26-
307+
+ [Event Grid](../event-grid/troubleshoot-errors.md)
27308
+ [Event Hubs](functions-bindings-event-hubs-output.md#exceptions-and-return-codes)
28-
29309
+ [IoT Hubs](functions-bindings-event-iot-output.md#exceptions-and-return-codes)
30-
31310
+ [Notification Hubs](functions-bindings-notification-hubs.md#exceptions-and-return-codes)
32-
33311
+ [Queue storage](functions-bindings-storage-queue-output.md#exceptions-and-return-codes)
34-
35312
+ [Service Bus](functions-bindings-service-bus-output.md#exceptions-and-return-codes)
36-
37313
+ [Table storage](functions-bindings-storage-table-output.md#exceptions-and-return-codes)
314+
315+
## Next steps
316+
317+
+ [Azure Functions triggers and bindings concepts](functions-triggers-bindings.md)
318+
+ [Best practices for reliable Azure Functions](functions-best-practices.md)

articles/azure-functions/functions-bindings-errors.md

Lines changed: 0 additions & 13 deletions
This file was deleted.

articles/azure-functions/functions-host-json.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ Configuration settings can be found in [Storage queue triggers and bindings](fun
387387

388388
## retry
389389

390-
Controls the [retry policy](./functions-bindings-error-pages.md#retry-policies-preview) options for all executions in the app.
390+
Controls the [retry policy](./functions-bindings-error-pages.md#retry-policies) options for all executions in the app.
391391

392392
```json
393393
{

0 commit comments

Comments
 (0)