Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/Analyzers.targets
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<PackageReference Include="SonarAnalyzer.CSharp" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)analyzers\BannedSymbols.txt" Condition=" '$(IsTestProject)' != 'true' " Visible="false" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)analyzers\SonarLint.xml" Visible="False" />
<AdditionalFiles Include="$(MsBuildThisFileDirectory)analyzers\Stylecop.json" Visible="false" />
<EditorConfigFiles Include="$(MsBuildThisFileDirectory)analyzers\Stylecop.globalconfig" />
<EditorConfigFiles Include="$(MsBuildThisFileDirectory)analyzers\$(ProjectType).globalconfig" />
Expand Down
14 changes: 14 additions & 0 deletions eng/analyzers/SonarLint.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<AnalysisInput>
<Rules>
<Rule>
<Key>S103</Key>
<Parameters>
<Parameter>
<Key>maximumLineLength</Key>
<Value>500</Value>
</Parameter>
</Parameters>
</Rule>
</Rules>
</AnalysisInput>
5 changes: 4 additions & 1 deletion src/Polly/Fallback/AsyncFallbackPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ protected override Task ImplementationAsync(
/// <inheritdoc/>
protected override Task<TResult> ImplementationAsync<TResult>(Func<Context, CancellationToken, Task<TResult>> 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<Whatever>.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<Whatever>.Fallback<{nameof(TResult)}>(/* some {nameof(TResult)} value or Func<..., {nameof(TResult)}> */);");
}

/// <summary>
Expand Down
5 changes: 4 additions & 1 deletion src/Polly/Fallback/FallbackPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ protected override void Implementation(Action<Context, CancellationToken> action

/// <inheritdoc/>
protected override TResult Implementation<TResult>(Func<Context, CancellationToken, TResult> 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<Whatever>.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<Whatever>.Fallback<{nameof(TResult)}>(/* some {nameof(TResult)} value or Func<..., {nameof(TResult)}> */);");
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Polly/Polly.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<ProjectType>Library</ProjectType>
<MutationScore>70</MutationScore>
<IncludePollyUsings>true</IncludePollyUsings>
<NoWarn>$(NoWarn);IDE0011;S103;S3872;SA1402;SA1414;S3215</NoWarn>
<NoWarn>$(NoWarn);IDE0011;S3872;SA1402;SA1414;S3215</NoWarn>
<NoWarn>$(NoWarn);IDE1006;CA1062;S107;CA1068;S4039;CA1000;CA1063;CA1031;CA1051</NoWarn>
<NoWarn>$(NoWarn);CA2211;S2223;CA1032;CA1815;CA1816;S4457;SA1615;CA1033</NoWarn>
<NoWarn>$(NoWarn);S4023;CA1010;S3442;CA1064;SA1649;SA1625;SA1623;SA1118</NoWarn>
Expand Down
8 changes: 7 additions & 1 deletion src/Polly/Timeout/TimeoutEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ internal static TResult Implementation<TResult>(
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.
{
Expand Down