The program below behaves as expected for three retries but then crashes:

$ ./PollyTest/bin/Debug/net8.0/PollyTest.exe
Hello, World!
retry number 0
retry number 1
retry number 2
Unhandled exception. System.ApplicationException: work work
   at Program.<<Main>$>g__WorkAsync|0_1(CancellationToken token) in C:\git\test\pollytest\PollyTest\PollyTest\Program.cs:line 34
   at Program.<>c.<<<Main>$>b__0_0>d.MoveNext() in C:\git\test\pollytest\PollyTest\PollyTest\Program.cs:line 25
--- End of stack trace from previous location ---
   at Polly.ResiliencePipeline.<>c.<<ExecuteAsync>b__3_0>d.MoveNext()
--- End of stack trace from previous location ---
   at Polly.Outcome`1.GetResultOrRethrow()
   at Polly.ResiliencePipeline.ExecuteAsync(Func`2 callback, CancellationToken cancellationToken)
   at Program.<Main>$(String[] args) in C:\git\test\pollytest\PollyTest\PollyTest\Program.cs:line 23
   at Program.<Main>(String[] args)
$

with the following source code:

using Polly.Retry;
using Polly;

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

var retryOptions = new RetryStrategyOptions
{
    BackoffType = DelayBackoffType.Exponential,
    Delay = TimeSpan.FromMilliseconds(100),
    MaxDelay = TimeSpan.FromSeconds(60),
    OnRetry = arguments =>
    {
        Console.WriteLine($"retry number {arguments.AttemptNumber}");
        return default;
    },
    ShouldHandle = args => PredicateResult.True(),
};
var pipeline = new ResiliencePipelineBuilder()
    .AddRetry(retryOptions)
    .Build();

await pipeline.ExecuteAsync(async token =>
{
    await WorkAsync(token);
}, CancellationToken.None);

return;

///////////////////////////////////

static Task WorkAsync(CancellationToken token)
{
    throw new ApplicationException("work work");
}

When running in debug mode in Visual Studio, the following is printed in the Debug output

...
'PollyTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.2\System.ObjectModel.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'PollyTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.2\System.Collections.Concurrent.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'PollyTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.2\System.Private.Uri.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Exception thrown: 'System.ApplicationException' in PollyTest.dll
Exception thrown: 'System.ApplicationException' in PollyTest.dll
Exception thrown: 'System.ApplicationException' in PollyTest.dll
Exception thrown: 'System.ApplicationException' in PollyTest.dll
Exception thrown: 'System.ApplicationException' in System.Private.CoreLib.dll
An exception of type 'System.ApplicationException' occurred in System.Private.CoreLib.dll but was not handled in user code
work work

so obviously all Exception thrown: ... in PollyTest.dll are captured and handled as expected but Exception thrown: ... in System.Private.CoreLib.dll is not. But why is suddenly System.Private.CoreLib.dll involved? How can I avoid?

This is with Polly version 8.3.0.

1

There are 1 best solutions below

0
Peter Csala On

Your observed behavior has nothing to do with Polly. If you remove the retry logic from your application and execute directly the WorkAsync

change from

await pipeline.ExecuteAsync(async token =>
{
    await WorkAsync(token);
}, CancellationToken.None);

to

await WorkAsync(CancellationToken.None);

then you will see the exact same behavior.


The System.ApplicationException is defined inside the System.Runtime.dll which is a reference assembly. The implementation assembly of this type is System.Private.CoreLib.dll.

So, that's the reason why do you see System.Private.CoreLib.dll in your standard output / error.