Skip to content

Commit ed1c79b

Browse files
authored
Fix CA1062 warnings (#2223)
Fix warnings for `AsyncRateLimitPolicy`.
1 parent 6d2b4e9 commit ed1c79b

File tree

5 files changed

+94
-9
lines changed

5 files changed

+94
-9
lines changed

src/Polly/RateLimit/AsyncRateLimitPolicy.cs

+38-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ namespace Polly.RateLimit;
44
/// <summary>
55
/// A rate-limit policy that can be applied to asynchronous delegates.
66
/// </summary>
7-
#pragma warning disable CA1062 // Validate arguments of public methods
87
public class AsyncRateLimitPolicy : AsyncPolicy, IRateLimitPolicy
98
{
109
private readonly IRateLimiter _rateLimiter;
@@ -14,9 +13,25 @@ internal AsyncRateLimitPolicy(IRateLimiter rateLimiter) =>
1413

1514
/// <inheritdoc/>
1615
[DebuggerStepThrough]
17-
protected override Task<TResult> ImplementationAsync<TResult>(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken,
18-
bool continueOnCapturedContext) =>
19-
AsyncRateLimitEngine.ImplementationAsync(_rateLimiter, null, action, context, continueOnCapturedContext, cancellationToken);
16+
protected override Task<TResult> ImplementationAsync<TResult>(
17+
Func<Context, CancellationToken, Task<TResult>> action,
18+
Context context,
19+
CancellationToken cancellationToken,
20+
bool continueOnCapturedContext)
21+
{
22+
if (action is null)
23+
{
24+
throw new ArgumentNullException(nameof(action));
25+
}
26+
27+
return AsyncRateLimitEngine.ImplementationAsync(
28+
_rateLimiter,
29+
null,
30+
action,
31+
context,
32+
continueOnCapturedContext,
33+
cancellationToken);
34+
}
2035
}
2136

2237
/// <summary>
@@ -38,7 +53,23 @@ internal AsyncRateLimitPolicy(
3853

3954
/// <inheritdoc/>
4055
[DebuggerStepThrough]
41-
protected override Task<TResult> ImplementationAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken,
42-
bool continueOnCapturedContext) =>
43-
AsyncRateLimitEngine.ImplementationAsync(_rateLimiter, _retryAfterFactory, action, context, continueOnCapturedContext, cancellationToken);
56+
protected override Task<TResult> ImplementationAsync(
57+
Func<Context, CancellationToken, Task<TResult>> action,
58+
Context context,
59+
CancellationToken cancellationToken,
60+
bool continueOnCapturedContext)
61+
{
62+
if (action is null)
63+
{
64+
throw new ArgumentNullException(nameof(action));
65+
}
66+
67+
return AsyncRateLimitEngine.ImplementationAsync(
68+
_rateLimiter,
69+
_retryAfterFactory,
70+
action,
71+
context,
72+
continueOnCapturedContext,
73+
cancellationToken);
74+
}
4475
}

test/Polly.Specs/NoOp/NoOpSpecs.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public void Should_throw_when_action_is_null()
1818

1919
var exceptionAssertions = func.Should().Throw<TargetInvocationException>();
2020
exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation.");
21-
exceptionAssertions.WithInnerException<ArgumentNullException>("action");
21+
exceptionAssertions.And.InnerException.Should().BeOfType<ArgumentNullException>()
22+
.Which.ParamName.Should().Be("action");
2223
}
2324

2425
[Fact]

test/Polly.Specs/NoOp/NoOpTResultAsyncSpecs.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ public void Should_throw_when_action_is_null()
1717

1818
var exceptionAssertions = func.Should().Throw<TargetInvocationException>();
1919
exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation.");
20-
exceptionAssertions.WithInnerException<ArgumentNullException>("action");
20+
exceptionAssertions.And.InnerException.Should().BeOfType<ArgumentNullException>()
21+
.Which.ParamName.Should().Be("action");
2122
}
2223

2324
[Fact]

test/Polly.Specs/RateLimit/AsyncRateLimitPolicySpecs.cs

+26
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,30 @@ protected override (bool, TimeSpan) TryExecuteThroughPolicy(IRateLimitPolicy pol
3131
throw new InvalidOperationException("Unexpected policy type in test construction.");
3232
}
3333
}
34+
35+
[Fact]
36+
public void Should_throw_when_action_is_null()
37+
{
38+
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
39+
Func<Context, CancellationToken, Task<EmptyStruct>> action = null!;
40+
IRateLimiter rateLimiter = RateLimiterFactory.Create(TimeSpan.FromSeconds(1), 1);
41+
42+
var instance = Activator.CreateInstance(
43+
typeof(AsyncRateLimitPolicy),
44+
flags,
45+
null,
46+
[rateLimiter],
47+
null)!;
48+
var instanceType = instance.GetType();
49+
var methods = instanceType.GetMethods(flags);
50+
var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" });
51+
var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct));
52+
53+
var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None, false]);
54+
55+
var exceptionAssertions = func.Should().Throw<TargetInvocationException>();
56+
exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation.");
57+
exceptionAssertions.And.InnerException.Should().BeOfType<ArgumentNullException>()
58+
.Which.ParamName.Should().Be("action");
59+
}
3460
}

test/Polly.Specs/RateLimit/AsyncRateLimitPolicyTResultSpecs.cs

+26
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,30 @@ protected override TResult TryExecuteThroughPolicy<TResult>(IRateLimitPolicy<TRe
4747
throw new InvalidOperationException("Unexpected policy type in test construction.");
4848
}
4949
}
50+
51+
[Fact]
52+
public void Should_throw_when_action_is_null()
53+
{
54+
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
55+
Func<Context, CancellationToken, Task<EmptyStruct>> action = null!;
56+
IRateLimiter rateLimiter = RateLimiterFactory.Create(TimeSpan.FromSeconds(1), 1);
57+
Func<TimeSpan, Context, EmptyStruct>? retryAfterFactory = null!;
58+
59+
var instance = Activator.CreateInstance(
60+
typeof(AsyncRateLimitPolicy<EmptyStruct>),
61+
flags,
62+
null,
63+
[rateLimiter, retryAfterFactory],
64+
null)!;
65+
var instanceType = instance.GetType();
66+
var methods = instanceType.GetMethods(flags);
67+
var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" });
68+
69+
var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken.None, false]);
70+
71+
var exceptionAssertions = func.Should().Throw<TargetInvocationException>();
72+
exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation.");
73+
exceptionAssertions.And.InnerException.Should().BeOfType<ArgumentNullException>()
74+
.Which.ParamName.Should().Be("action");
75+
}
5076
}

0 commit comments

Comments
 (0)