From 5785f448b108ad2303c6cf2bce07ed31c0f3e7db Mon Sep 17 00:00:00 2001 From: ZLoo Date: Mon, 22 Jul 2024 19:50:06 +0300 Subject: [PATCH 1/2] Fix warning CA1062#TimeoutPolicy --- src/Polly/Timeout/TimeoutPolicy.cs | 23 +++++++++++---- test/Polly.Specs/Timeout/TimeoutSpecs.cs | 28 +++++++++++++++++++ .../Timeout/TimeoutTResultSpecs.cs | 27 ++++++++++++++++++ 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/Polly/Timeout/TimeoutPolicy.cs b/src/Polly/Timeout/TimeoutPolicy.cs index 1f638ccceae..2e05f6a144e 100644 --- a/src/Polly/Timeout/TimeoutPolicy.cs +++ b/src/Polly/Timeout/TimeoutPolicy.cs @@ -3,7 +3,6 @@ /// /// A timeout policy which can be applied to delegates. /// -#pragma warning disable CA1062 // Validate arguments of public methods public class TimeoutPolicy : Policy, ITimeoutPolicy { private readonly TimeoutStrategy _timeoutStrategy; @@ -22,14 +21,21 @@ internal TimeoutPolicy( /// [DebuggerStepThrough] - protected override TResult Implementation(Func action, Context context, CancellationToken cancellationToken) => - TimeoutEngine.Implementation( + protected override TResult Implementation(Func action, Context context, CancellationToken cancellationToken) + { + if (action is null) + { + throw new ArgumentNullException(nameof(action)); + } + + return TimeoutEngine.Implementation( action, context, _timeoutProvider, _timeoutStrategy, _onTimeout, cancellationToken); + } } /// @@ -53,12 +59,19 @@ internal TimeoutPolicy( } /// - protected override TResult Implementation(Func action, Context context, CancellationToken cancellationToken) => - TimeoutEngine.Implementation( + protected override TResult Implementation(Func action, Context context, CancellationToken cancellationToken) + { + if (action is null) + { + throw new ArgumentNullException(nameof(action)); + } + + return TimeoutEngine.Implementation( action, context, _timeoutProvider, _timeoutStrategy, _onTimeout, cancellationToken); + } } diff --git a/test/Polly.Specs/Timeout/TimeoutSpecs.cs b/test/Polly.Specs/Timeout/TimeoutSpecs.cs index d7e1ea34481..c350f18ea99 100644 --- a/test/Polly.Specs/Timeout/TimeoutSpecs.cs +++ b/test/Polly.Specs/Timeout/TimeoutSpecs.cs @@ -5,6 +5,34 @@ public class TimeoutSpecs : TimeoutSpecsBase { #region Configuration + [Fact] + public void Should_throw_when_action_is_null() + { + var flags = BindingFlags.NonPublic | BindingFlags.Instance; + Func action = null!; + Func timeoutProvider = (_) => TimeSpan.Zero; + TimeoutStrategy timeoutStrategy = TimeoutStrategy.Optimistic; + Action onTimeout = (_ , _, _, _) => {}; + + var instance = Activator.CreateInstance( + typeof(TimeoutPolicy), + flags, + null, + [timeoutProvider, timeoutStrategy, onTimeout], + null)!; + var instanceType = instance.GetType(); + var methods = instanceType.GetMethods(flags); + var methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "TResult" }); + var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); + + var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None]); + + var exceptionAssertions = func.Should().Throw(); + exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); + exceptionAssertions.And.InnerException.Should().BeOfType() + .Which.ParamName.Should().Be("action"); + } + [Fact] public void Should_throw_when_timeout_is_zero_by_timespan() { diff --git a/test/Polly.Specs/Timeout/TimeoutTResultSpecs.cs b/test/Polly.Specs/Timeout/TimeoutTResultSpecs.cs index 202ed090380..18330810f67 100644 --- a/test/Polly.Specs/Timeout/TimeoutTResultSpecs.cs +++ b/test/Polly.Specs/Timeout/TimeoutTResultSpecs.cs @@ -5,6 +5,33 @@ public class TimeoutTResultSpecs : TimeoutSpecsBase { #region Configuration + [Fact] + public void Should_throw_when_action_is_null() + { + var flags = BindingFlags.NonPublic | BindingFlags.Instance; + Func action = null!; + Func timeoutProvider = (_) => TimeSpan.Zero; + TimeoutStrategy timeoutStrategy = TimeoutStrategy.Optimistic; + Action onTimeout = (_, _, _, _) => { }; + + var instance = Activator.CreateInstance( + typeof(TimeoutPolicy), + flags, + null, + [timeoutProvider, timeoutStrategy, onTimeout], + null)!; + var instanceType = instance.GetType(); + var methods = instanceType.GetMethods(flags); + var methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "EmptyStruct" }); + + var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken.None]); + + var exceptionAssertions = func.Should().Throw(); + exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); + exceptionAssertions.And.InnerException.Should().BeOfType() + .Which.ParamName.Should().Be("action"); + } + [Fact] public void Should_throw_when_timeout_is_zero_by_timespan() { From eb14a11a74b03fa06c184f97ff76a930ab46c8d7 Mon Sep 17 00:00:00 2001 From: ZLoo Date: Mon, 22 Jul 2024 20:01:52 +0300 Subject: [PATCH 2/2] fix IDE0055 --- test/Polly.Specs/Timeout/TimeoutSpecs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Polly.Specs/Timeout/TimeoutSpecs.cs b/test/Polly.Specs/Timeout/TimeoutSpecs.cs index c350f18ea99..76e1cdf5d55 100644 --- a/test/Polly.Specs/Timeout/TimeoutSpecs.cs +++ b/test/Polly.Specs/Timeout/TimeoutSpecs.cs @@ -12,7 +12,7 @@ public void Should_throw_when_action_is_null() Func action = null!; Func timeoutProvider = (_) => TimeSpan.Zero; TimeoutStrategy timeoutStrategy = TimeoutStrategy.Optimistic; - Action onTimeout = (_ , _, _, _) => {}; + Action onTimeout = (_, _, _, _) => { }; var instance = Activator.CreateInstance( typeof(TimeoutPolicy),