diff --git a/eng/Analyzers.targets b/eng/Analyzers.targets
index a3a37e46713..01c0a55faf3 100644
--- a/eng/Analyzers.targets
+++ b/eng/Analyzers.targets
@@ -4,6 +4,7 @@
+
diff --git a/eng/analyzers/SonarLint.xml b/eng/analyzers/SonarLint.xml
new file mode 100644
index 00000000000..9386ae4545c
--- /dev/null
+++ b/eng/analyzers/SonarLint.xml
@@ -0,0 +1,14 @@
+
+
+
+
+ S103
+
+
+ maximumLineLength
+ 500
+
+
+
+
+
diff --git a/src/Polly/Bulkhead/AsyncBulkheadSyntax.cs b/src/Polly/Bulkhead/AsyncBulkheadSyntax.cs
index f31052e1691..9ce2c947da3 100644
--- a/src/Polly/Bulkhead/AsyncBulkheadSyntax.cs
+++ b/src/Polly/Bulkhead/AsyncBulkheadSyntax.cs
@@ -24,7 +24,6 @@ public static AsyncBulkheadPolicy BulkheadAsync(int maxParallelization)
/// The policy instance.
/// maxParallelization;Value must be greater than zero.
/// Thrown when is .
- /// The policy instance.
public static AsyncBulkheadPolicy BulkheadAsync(int maxParallelization, Func onBulkheadRejectedAsync) =>
BulkheadAsync(maxParallelization, 0, onBulkheadRejectedAsync);
diff --git a/src/Polly/Bulkhead/BulkheadSyntax.cs b/src/Polly/Bulkhead/BulkheadSyntax.cs
index 7b1b7515471..afd10398d9d 100644
--- a/src/Polly/Bulkhead/BulkheadSyntax.cs
+++ b/src/Polly/Bulkhead/BulkheadSyntax.cs
@@ -52,7 +52,7 @@ public static BulkheadPolicy Bulkhead(int maxParallelization, int maxQueuingActi
/// An action to call, if the bulkhead rejects execution due to oversubscription.
/// The policy instance.
/// maxParallelization;Value must be greater than zero.
- /// maxParallelization;Value must be greater than zero.
+ /// maxQueuingActions;Value must be greater than or equal to zero.
/// Thrown when is .
public static BulkheadPolicy Bulkhead(int maxParallelization, int maxQueuingActions, Action onBulkheadRejected)
{
diff --git a/src/Polly/Fallback/AsyncFallbackPolicy.cs b/src/Polly/Fallback/AsyncFallbackPolicy.cs
index 6d9ef1d5ff0..5c42f6dc59a 100644
--- a/src/Polly/Fallback/AsyncFallbackPolicy.cs
+++ b/src/Polly/Fallback/AsyncFallbackPolicy.cs
@@ -45,7 +45,10 @@ protected override Task ImplementationAsync(
///
protected override Task ImplementationAsync(Func> action, Context context, CancellationToken cancellationToken,
bool continueOnCapturedContext) =>
- throw new InvalidOperationException($"You have executed the generic .Execute<{nameof(TResult)}> method on a non-generic {nameof(FallbackPolicy)}. A non-generic {nameof(FallbackPolicy)} only defines a fallback action which returns void; it can never return a substitute {nameof(TResult)} value. To use {nameof(FallbackPolicy)} to provide fallback {nameof(TResult)} values you must define a generic fallback policy {nameof(FallbackPolicy)}<{nameof(TResult)}>. For example, define the policy as Policy<{nameof(TResult)}>.Handle.Fallback<{nameof(TResult)}>(/* some {nameof(TResult)} value or Func<..., {nameof(TResult)}> */);");
+ throw new InvalidOperationException($"You have executed the generic .Execute<{nameof(TResult)}> method on a non-generic {nameof(FallbackPolicy)}. " +
+ $"A non-generic {nameof(FallbackPolicy)} only defines a fallback action which returns void; it can never return a substitute {nameof(TResult)} value. " +
+ $"To use {nameof(FallbackPolicy)} to provide fallback {nameof(TResult)} values you must define a generic fallback policy {nameof(FallbackPolicy)}<{nameof(TResult)}>. " +
+ $"For example, define the policy as Policy<{nameof(TResult)}>.Handle.Fallback<{nameof(TResult)}>(/* some {nameof(TResult)} value or Func<..., {nameof(TResult)}> */);");
}
///
diff --git a/src/Polly/Fallback/FallbackPolicy.cs b/src/Polly/Fallback/FallbackPolicy.cs
index 3deeaeea9f0..808f535263e 100644
--- a/src/Polly/Fallback/FallbackPolicy.cs
+++ b/src/Polly/Fallback/FallbackPolicy.cs
@@ -42,7 +42,10 @@ protected override void Implementation(Action action
///
protected override TResult Implementation(Func action, Context context, CancellationToken cancellationToken) =>
- throw new InvalidOperationException($"You have executed the generic .Execute<{nameof(TResult)}> method on a non-generic {nameof(FallbackPolicy)}. A non-generic {nameof(FallbackPolicy)} only defines a fallback action which returns void; it can never return a substitute {nameof(TResult)} value. To use {nameof(FallbackPolicy)} to provide fallback {nameof(TResult)} values you must define a generic fallback policy {nameof(FallbackPolicy)}<{nameof(TResult)}>. For example, define the policy as Policy<{nameof(TResult)}>.Handle.Fallback<{nameof(TResult)}>(/* some {nameof(TResult)} value or Func<..., {nameof(TResult)}> */);");
+ throw new InvalidOperationException($"You have executed the generic .Execute<{nameof(TResult)}> method on a non-generic {nameof(FallbackPolicy)}. " +
+ $"A non-generic {nameof(FallbackPolicy)} only defines a fallback action which returns void; it can never return a substitute {nameof(TResult)} value. " +
+ $"To use {nameof(FallbackPolicy)} to provide fallback {nameof(TResult)} values you must define a generic fallback policy {nameof(FallbackPolicy)}<{nameof(TResult)}>. " +
+ $"For example, define the policy as Policy<{nameof(TResult)}>.Handle.Fallback<{nameof(TResult)}>(/* some {nameof(TResult)} value or Func<..., {nameof(TResult)}> */);");
}
///
diff --git a/src/Polly/Polly.csproj b/src/Polly/Polly.csproj
index 891435d1544..58e363a6f20 100644
--- a/src/Polly/Polly.csproj
+++ b/src/Polly/Polly.csproj
@@ -7,14 +7,14 @@
Library
70
true
- $(NoWarn);S103;S3872;SA1402;SA1414;S3215
+ $(NoWarn);S3872;SA1402;SA1414;S3215
$(NoWarn);IDE1006;CA1062;S107;CA1068;S4039;CA1000;CA1063;CA1031;CA1051
$(NoWarn);CA2211;S2223;CA1032;CA1815;CA1816;S4457;SA1615;CA1033
- $(NoWarn);S4023;CA1010;S3442;CA1064;SA1649;SA1625;SA1623;SA1118
- $(NoWarn);S3253;S3971;S6605;CA1724;CA1716;SA1108;CA1710;S4049;S3246
+ $(NoWarn);S4023;CA1010;S3442;CA1064;SA1649;SA1623;SA1118
+ $(NoWarn);S3971;CA1724;CA1716;SA1108;CA1710;S4049;S3246
$(NoWarn);CA1805
-
+
$(NoWarn);RS0037;
diff --git a/src/Polly/ResultPredicates.cs b/src/Polly/ResultPredicates.cs
index ed98c3b317b..d5007f19e67 100644
--- a/src/Polly/ResultPredicates.cs
+++ b/src/Polly/ResultPredicates.cs
@@ -26,7 +26,7 @@ public bool AnyMatch(TResult result)
return false;
}
- return _predicates.Any(predicate => predicate(result));
+ return _predicates.Exists(predicate => predicate(result));
}
///
diff --git a/src/Polly/Timeout/AsyncTimeoutSyntax.cs b/src/Polly/Timeout/AsyncTimeoutSyntax.cs
index 5cb7153ac89..e1fcac99129 100644
--- a/src/Polly/Timeout/AsyncTimeoutSyntax.cs
+++ b/src/Polly/Timeout/AsyncTimeoutSyntax.cs
@@ -85,7 +85,7 @@ public static AsyncTimeoutPolicy TimeoutAsync(int seconds, FuncThe Task parameter will be null if the executed action responded cooperatively to cancellation before the policy timed it out.
/// The policy instance.
/// seconds;Value must be greater than zero.
- /// seconds;Value must be greater than zero.
+ /// Thrown when is .
public static AsyncTimeoutPolicy TimeoutAsync(int seconds, TimeoutStrategy timeoutStrategy, Func onTimeoutAsync)
{
TimeoutValidator.ValidateSecondsTimeout(seconds);
@@ -102,7 +102,7 @@ public static AsyncTimeoutPolicy TimeoutAsync(int seconds, TimeoutStrategy timeo
/// The Task parameter will be null if the executed action responded cooperatively to cancellation before the policy timed it out.
/// The policy instance.
/// seconds;Value must be greater than zero.
- /// seconds;Value must be greater than zero.
+ /// Thrown when is .
public static AsyncTimeoutPolicy TimeoutAsync(int seconds, TimeoutStrategy timeoutStrategy, Func onTimeoutAsync)
{
if (seconds <= 0)
diff --git a/src/Polly/Timeout/TimeoutEngine.cs b/src/Polly/Timeout/TimeoutEngine.cs
index 150adf32c22..5bed28927e7 100644
--- a/src/Polly/Timeout/TimeoutEngine.cs
+++ b/src/Polly/Timeout/TimeoutEngine.cs
@@ -38,7 +38,13 @@ internal static TResult Implementation(
combinedToken); // cancellation token here only allows Task.Run() to not begin the passed delegate at all, if cancellation occurs prior to invoking the delegate.
try
{
- actionTask.Wait(timeoutCancellationTokenSource.Token); // cancellation token here cancels the Wait() and causes it to throw, but does not cancel actionTask. We use only timeoutCancellationTokenSource.Token here, not combinedToken. If we allowed the user's cancellation token to cancel the Wait(), in this pessimistic scenario where the user delegate may not observe that cancellation, that would create a no-longer-observed task. That task could in turn later fault before completing, risking an UnobservedTaskException.
+ /*
+ * Cancellation token here cancels the Wait() and causes it to throw, but does not cancel actionTask.
+ * We use only timeoutCancellationTokenSource.Token here, not combinedToken.
+ * If we allowed the user's cancellation token to cancel the Wait(), in this pessimistic scenario where the user delegate may not observe that cancellation, that would create a no-longer-observed task.
+ * That task could in turn later fault before completing, risking an UnobservedTaskException.
+ */
+ actionTask.Wait(timeoutCancellationTokenSource.Token);
}
catch (AggregateException ex) when (ex.InnerExceptions.Count == 1) // Issue #270. Unwrap extra AggregateException caused by the way pessimistic timeout policy for synchronous executions is necessarily constructed.
{