Repository navigation
Closed
Labels
area-resiliencebugThis issue describes a behavior which is not expected - a bug.This issue describes a behavior which is not expected - a bug.
Description
Description
My unit tests randomly crash while starting the host due to a InvalidCastException in option validation for standard resilience handler.
Reproduction Steps
Hard to reproduce as it is a race condition and occurs randomly.
However my tests looks like something like this :
await new HostBuilder()
.ConfigureDefaults([])
.ConfigureServices(services =>
{
services.AddHttpClient<FooClient>()
.AddStandardResilienceHandler();
services.AddHttpClient<BarClient>()
.AddStandardResilienceHandler();
})
.StartAsync();
Expected behavior
Works correclty
Actual behavior
The current exception
fail: Microsoft.Extensions.Hosting.Internal.Host[11]
Hosting failed to start
System.InvalidCastException: Unable to cast object of type 'System.TimeSpan' to type 'System.String'.
at __OptionValidationGeneratedAttributes.<Validators_g>F8B1F3D42962A35D8FF1B1489612AEF6C36F3713335EFF79DB68A25973333C495____SourceGen__RangeAttribute.IsValid(Object value)
at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext)
at System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext)
at System.ComponentModel.DataAnnotations.Validator.TryValidate(Object value, ValidationContext validationContext, ValidationAttribute attribute, ValidationError& validationError)
at System.ComponentModel.DataAnnotations.Validator.GetValidationErrors(Object value, ValidationContext validationContext, IEnumerable`1 attributes, Boolean breakOnFirstError)
at System.ComponentModel.DataAnnotations.Validator.TryValidateValue(Object value, ValidationContext validationContext, ICollection`1 validationResults, IEnumerable`1 validationAttributes)
at Microsoft.Extensions.Http.Resilience.__HttpRetryStrategyOptionsValidator__.Validate(String name, HttpRetryStrategyOptions options)
at Microsoft.Extensions.Http.Resilience.Internal.Validators.HttpStandardResilienceOptionsValidator.Validate(String name, HttpStandardResilienceOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c.<Get>b__10_0(String name, IOptionsFactory`1 factory)
at Microsoft.Extensions.Options.OptionsCache`1.<>c__DisplayClass3_1`1.<GetOrAdd>b__2()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd[TArg](String name, Func`3 createOptions, TArg factoryArgument)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.Extensions.DependencyInjection.OptionsBuilderExtensions.<>c__DisplayClass0_1`1.<ValidateOnStart>b__1()
at Microsoft.Extensions.Options.StartupValidator.Validate()
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
Regression?
No response
Known Workarounds
No response
Configuration
dotnet 8
Microsoft.Extensions.Http.Resilience Version="8.1.0"
Other information
I've been able to debug the exception and walk through the stack.
As you can see we are in the !IsInitialized if branch even though the IsInitialized is true, an other thread must have set it concurrently and then Minimum and Maximum are already Timespan, not strings.

Metadata
Metadata
Assignees
Labels
area-resiliencebugThis issue describes a behavior which is not expected - a bug.This issue describes a behavior which is not expected - a bug.
Activity
NatMarchand commentedon Feb 2, 2024
Ah! Just found that it was corrected in the source generator !
dotnet/runtime#97045
martincostello commentedon Feb 13, 2024
The package with the fix for the source generator has been released today, 8.0.2, but I think we need a new version of the
Microsoft.Extensions.Http.Resiliencelibrary built using that version of the source generator to propagate out the fix.NatMarchand commentedon Feb 15, 2024
Looks like 8.2.0 contains the fix. Closing the issue !