Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

220
Visualizações
Polly policy to log exception and rethrow

I consider to use Polly to create policy to log exception and rethrow. I didn't find an existing method that allow it out of the box , but some options that I see are

Fallback

// Specify a substitute value or func, calling an action (e.g. for logging)
// if the fallback is invoked.
Policy.Handle<Whatever>()
.Fallback<UserAvatar>(UserAvatar.Blank,
    onFallback: (exception, context) =>
    {
        _logger.Log(exception, context);
        throw exception;
    });

Question: is it ok to throw exception from Fallback?

Timeout

Policy.Timeout(1, T30meoutStrategy.Pessimistic,
(context, timespan, task) =>
{
    // ContinueWith important!: the abandoned task may very well still be executing,
    // when the caller times out on waiting for it!
    task.ContinueWith(t =>
    {
        if (t.IsFaulted)
        {
            logger.Error(context,t.Exception);
            throw exception;
        }
    });
}

Or Retry

Policy.Handle<DivideByZeroException>().Retry(0,
(exception, retryCount) =>
{
    logger.Error(context,exception);
    throw exception;
});

Question: is 0 retries supported?

Or KISS and write simple try/catch with throw by myself.

Which of these methods is better? What are your recommendation?

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

If you do not already have Polly in the mix, try/catch would seem simplest.

If you already have Polly in the mix, FallbackPolicy can safely be re-purposed in the way you suggest. The onFallback delegate and fallback action or value are not governed by the .Handle<>() clauses of the Policy, so you can safely rethrow an exception from within the onFallback delegate.

Policy<UserAvatar>.Handle<Whatever>()
.Fallback<UserAvatar>(UserAvatar.Blank,
    onFallback: (exception, context) =>
    {
        _logger.Log(exception, context);
        throw exception;
    });

The approach your question outlines with TimeoutPolicy would only capture exceptions thrown by delegates the caller had earlier walked away from due to timeout, and only in TimeoutMode.Pessimistic; not all exceptions.


The approach your question outlines with .Retry(0, ...) would not work. If no retries are specified, the onRetry delegate would not be invoked.


To avoid the untidiness of repurposing FallbackPolicy, you could also code your own LogThenRethrowPolicy, within Polly's structures. This commit (which added the simple NoOpPolicy) exemplifies the minimum necessary to add a new policy. You could add an implementation similar to NoOpPolicy but just try { } catch { /* log; rethrow */ }


EDIT January 2019: Polly.Contrib now also contains a Polly.Contrib.LoggingPolicy which can help with this.

about 4 years ago · Santiago Trujillo Relatório

0

https://github.com/App-vNext/Polly-Samples/blob/master/PollyDemos/Async/AsyncDemo02_WaitAndRetryNTimes.cs shows that you can use the onRetry: option, at least for WaitAndRetryAsync. I haven't looked at the others yet.

HttpPolicyExtensions
.HandleTransientHttpError()
.WaitAndRetryAsync(3,
    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))  // exponential back-off: 2, 4, 8 etc
                    + TimeSpan.FromMilliseconds(Jitterer.Next(0, 1000)), // plus some jitter: up to 1 second
    onRetry: (response, calculatedWaitDuration) =>
    {
        logger.LogError($"Failed attempt. Waited for {calculatedWaitDuration}. Retrying. {response.Exception.Message} - {response.Exception.StackTrace}");
    }
);
about 4 years ago · Santiago Trujillo Relatório

0

Here my solution with generic method

public async Task<T> PollyRetry<T>(
        Func<Task<T>> action)
    {

        bool hasFallback = false;
        Exception ex = null;

        var fallbackPolicy = Policy<T>.Handle<Exception>().FallbackAsync(
            default(T), d =>
            {
                //log final exception

                ex = d.Exception;

                hasFallback = true;
                return Task.FromResult(new { });

            });

        var retryPolicy = Policy
            .Handle<Exception>()
            .WaitAndRetryAsync(3,
                retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                (res, timeSpan, context) =>
                {
                    //log exception
                });

        var policyResult = await fallbackPolicy.WrapAsync(retryPolicy).ExecuteAndCaptureAsync(action);

        if (hasFallback && ex != null)
            throw ex;

        return policyResult.Result;
    }

//call service with retry logic
        TestResponse response = await _pollyRetryService.PollyRetry(async () =>
        {
            return await _testService.Test(input);

        });
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda