You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Polly实现仅在错误码403002出现时重试3次deviceClient.SendEventAsync操作

Using Polly to Retry on Specific Error Code (403002) for Async Operation

Got it, let's break down how to implement this Polly retry logic for your specific scenario. You’re already parsing the error code correctly in your try-catch, so we just need to move that logic into Polly’s policy definition to clean things up and separate retry concerns from your business code.

Step 1: Create a Helper to Check Retry Eligibility

First, extract your error code validation into a reusable method. This will tell Polly whether an exception should trigger a retry:

private bool ShouldRetryOn403002(Exception ex)
{
    // Get the inner exception message where your error JSON lives
    var errorMessage = ex.InnerException?.Message;
    if (string.IsNullOrEmpty(errorMessage))
        return false;

    try
    {
        // Deserialize the error message and check the code
        dynamic error = JsonConvert.DeserializeObject(errorMessage);
        return error != null && error.errorCode == 403002;
    }
    catch (JsonException)
    {
        // If deserialization fails, this isn't the 403002 error we care about
        return false;
    }
}

Step 2: Build an Async Retry Policy

Since your SendEventAsync is an asynchronous method, you must use Polly's async-aware policies (don’t use the synchronous WaitAndRetry—it won’t work correctly with await). We’ll define a policy that retries only when our helper returns true, with configurable delays:

// Pull these values from your config (e.g., appsettings.json) for flexibility
int maxRetryAttempts = 3;
Func<int, TimeSpan> retryDelayStrategy = attempt => 
    TimeSpan.FromSeconds(Math.Pow(2, attempt)); // Exponential backoff (2s, 4s, 8s)
// Or use a fixed delay: _ => TimeSpan.FromSeconds(3)

var retryPolicy = Policy
    .Handle<Exception>(ex => ShouldRetryOn403002(ex))
    .WaitAndRetryAsync(
        retryCount: maxRetryAttempts,
        sleepDurationProvider: retryDelayStrategy,
        onRetry: (exception, timespan, retryAttempt, context) =>
        {
            // Log each retry for visibility
            _logger.LogWarning(
                $"Retry {retryAttempt}/{maxRetryAttempts} triggered for error code 403002. Waiting {timespan.TotalSeconds:F1}s before next attempt.");
        });

Step 3: Wrap Your Async Operation with the Policy

Replace your existing try-catch block with Polly’s ExecuteAsync method. Polly will handle retries automatically, and only throw an exception if retries are exhausted or the error isn’t eligible for retry:

try
{
    // Execute your send operation wrapped in the retry policy
    await retryPolicy.ExecuteAsync(async () =>
    {
        await deviceClient.SendEventAsync(new Message());
    });
}
catch (Exception ex)
{
    // This catches:
    // 1. Errors that aren't 403002 (no retries attempted)
    // 2. 403002 errors that failed all retry attempts
    _logger.LogError($"Operation failed after retries: {ex.Message}", ex);
    // Re-throw if you need to propagate the error upstream
    throw;
}

Optional: Externalize Configuration

To make your retry strategy configurable without changing code, add settings to appsettings.json:

"RetrySettings": {
    "MaxRetryAttempts": 3,
    "InitialDelaySeconds": 2
}

Then inject IConfiguration and read the values:

var maxRetryAttempts = _configuration.GetValue<int>("RetrySettings:MaxRetryAttempts");
var initialDelay = TimeSpan.FromSeconds(_configuration.GetValue<double>("RetrySettings:InitialDelaySeconds"));
var retryDelayStrategy = attempt => initialDelay * Math.Pow(2, attempt);

This approach keeps your business code clean, centralizes retry logic, and gives you flexibility to adjust retry behavior via config.

内容的提问来源于stack exchange,提问作者user584018

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:34:06