From 65d060c90f25536bfbaf7f8a760eed247a497f2d Mon Sep 17 00:00:00 2001 From: DualFroz Date: Wed, 2 Sep 2026 11:43:55 +0200 Subject: [PATCH] fix(simmy): return null from FaultGenerator when no fault is generated FaultGenerator's implicit conversion dereferenced the nullable Outcome returned by the underlying generator via `!.Value`, throwing InvalidOperationException ("Nullable object must have a value.") when the generator produced no outcome - an empty generator, or registered weights summing to zero. ChaosFaultStrategy treats a null fault as "do not inject" and only catches OperationCanceledException, so the exception escaped and failed the execution the strategy was meant to leave untouched. Propagate the nullable outcome with `?.Exception`, mirroring OutcomeGenerator, so no fault is injected when none is generated. --- src/Polly.Core/Simmy/Fault/FaultGenerator.cs | 2 +- .../Simmy/Fault/FaultGeneratorTests.cs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Polly.Core/Simmy/Fault/FaultGenerator.cs b/src/Polly.Core/Simmy/Fault/FaultGenerator.cs index c5931c0b161..cfb943f327c 100644 --- a/src/Polly.Core/Simmy/Fault/FaultGenerator.cs +++ b/src/Polly.Core/Simmy/Fault/FaultGenerator.cs @@ -78,6 +78,6 @@ public FaultGenerator AddException(int weight = DefaultWeight) var generatorDelegate = generator._helper.CreateGenerator(); - return args => new ValueTask(generatorDelegate(args.Context)!.Value.Exception); + return args => new ValueTask(generatorDelegate(args.Context)?.Exception); } } diff --git a/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs b/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs index 1b7e2cc99a0..fd77255d42f 100644 --- a/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs +++ b/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs @@ -39,6 +39,24 @@ public void AddException_FactoryWithResilienceContext_Ok() Generate(generator).ShouldBeOfType(); } + [Fact] + public void NoExceptionRegistered_ShouldReturnNull() + { + var generator = new FaultGenerator(); + + Generate(generator).ShouldBeNull(); + } + + [Fact] + public void AllWeightsZero_ShouldReturnNull() + { + var generator = new FaultGenerator(); + + generator.AddException(weight: 0); + + Generate(generator).ShouldBeNull(); + } + private static Exception? Generate(FaultGenerator generator) { Func> func = generator;