PipelineMessageClassifier
A classifier that can evaluate a PipelineMessage in two ways.
First, given an HTTP message, the PipelineMessageClassifier
can determine whether the service response it holds should be considered an
error response. Second, given an HTTP message and an optional pipeline
exception, the classifier can determine whether or not the
ClientPipeline should retry the request.
using System.ClientModel.Internal;
using System.IO;
using System.Runtime.CompilerServices;
namespace System.ClientModel.Primitives
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public abstract class PipelineMessageClassifier
{
[System.Runtime.CompilerServices.Nullable(0)]
internal class EndOfChainClassifier : PipelineMessageClassifier
{
public override bool TryClassify(PipelineMessage message, out bool isError)
{
Argument.AssertNotNull(message, "message");
message.AssertResponse();
int num = message.Response.Status / 100;
isError = (num == 4 || num == 5);
return true;
}
public override bool TryClassify(PipelineMessage message, [System.Runtime.CompilerServices.Nullable(2)] Exception exception, out bool isRetriable)
{
Argument.AssertNotNull(message, "message");
isRetriable = ((exception == null) ? IsRetriable(message) : IsRetriable(message, exception));
return true;
}
private static bool IsRetriable(PipelineMessage message)
{
message.AssertResponse();
switch (message.Response.Status) {
case 408:
return true;
case 429:
return true;
case 500:
return true;
case 502:
return true;
case 503:
return true;
case 504:
return true;
default:
return false;
}
}
private static bool IsRetriable(PipelineMessage message, Exception exception)
{
if (!IsRetriable(exception)) {
if (exception is OperationCanceledException)
return !message.CancellationToken.IsCancellationRequested;
return false;
}
return true;
}
private static bool IsRetriable(Exception exception)
{
if (!(exception is IOException)) {
ClientResultException ex = exception as ClientResultException;
if (ex != null)
return ex.Status == 0;
return false;
}
return true;
}
}
public static PipelineMessageClassifier Default { get; } = new EndOfChainClassifier();
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static PipelineMessageClassifier Create(ReadOnlySpan<ushort> successStatusCodes)
{
return new ResponseStatusClassifier(successStatusCodes);
}
public abstract bool TryClassify(PipelineMessage message, out bool isError);
public abstract bool TryClassify(PipelineMessage message, [System.Runtime.CompilerServices.Nullable(2)] Exception exception, out bool isRetriable);
}
}