PoliNorError.Extensions.Http 0.8.0

dotnet add package PoliNorError.Extensions.Http --version 0.8.0
                    
NuGet\Install-Package PoliNorError.Extensions.Http -Version 0.8.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PoliNorError.Extensions.Http" Version="0.8.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PoliNorError.Extensions.Http" Version="0.8.0" />
                    
Directory.Packages.props
<PackageReference Include="PoliNorError.Extensions.Http" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PoliNorError.Extensions.Http --version 0.8.0
                    
#r "nuget: PoliNorError.Extensions.Http, 0.8.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PoliNorError.Extensions.Http@0.8.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PoliNorError.Extensions.Http&version=0.8.0
                    
Install as a Cake Addin
#tool nuget:?package=PoliNorError.Extensions.Http&version=0.8.0
                    
Install as a Cake Tool

The library provides an outgoing request resiliency pipeline for HttpClient, using policies from the PoliNorError library.

⚑ Key Features

  • Provides the ability to create a resiliency pipeline to handle typical transient HTTP failures (including the HttpRequestException exception).
  • Flexible transient failure filter for the final DelegatingHandler in the pipeline for the response.
  • Additionally, custom failure status codes or categories can be added to the final handler filter.
  • Other exception types (besides HttpRequestException) can also be included in the final handler filter.
  • Inclusion in the outer handler filter of any Exception type thrown by the inner handler is also supported.
  • Both typed and named HttpClient, as well as IHttpClientFactory, can be used.
  • Targets .NET Standard 2.0.

πŸ”‘ Key Concepts

  • 🟦 Resiliency pipeline - the pipeline of DelegatingHandler, using policies from the PoliNorError library.
  • ➑ OuterHandler is the first handler in the pipeline (closest to the request initiator).
  • β¬… InnerHandler is the next handler in the pipeline (closer to the final destination).
  • πŸ”΅ FinalHandler is the innermost handler in the pipeline.
  • ❌ Transient HTTP errors are temporary failures that occur when making HTTP requests (HTTP 5xx, HTTP 408, HTTP 429 and HttpRequestException).

πŸš€ Usage

  1. Configure typed or named HttpClient:
services.AddHttpClient<IAskCatService, AskCatService>((sp, config) =>
	{
		...
		config.BaseAddress = new Uri(settings.BaseUri);
		...
	})...

, where AskCatService is a service that implements IAskCatService, with HttpClient or IHttpClientFactory injected.

  1. Use the library's IHttpClientBuilder.WithResiliencePipeline extension method and configure the pipeline of DelegatingHandlers by using the AddPolicyHandler method with the policy you want to apply in this handler:
services.AddHttpClient<IAskCatService, AskCatService>((spForClient, client) =>
	{
			...
	})
	.WithResiliencePipeline((pb) => 
		pb
		.AddPolicyHandler(PolicyJustCreated)
		.AddPolicyHandler((IServiceProvider sp) => funcThatUsesServiceProviderToCreatePolicy(sp))
		...
	)

Or use the WithResiliencePipeline method overload that includes an additional context parameter:

services.AddHttpClient<IAskCatService, AskCatService>((spForClient, client) =>
	{
			...
	})
	.WithResiliencePipeline<SomeContextType>((pb) => 
		pb
		.AddPolicyHandler((SomeContextType ctx, IServiceProvider sp) => 
			funcThatUsesContextAndServiceProviderToCreatePolicy(ctx, sp))

		.AddPolicyHandler((IServiceProvider sp) => funcThatUsesServiceProviderToCreatePolicy(sp))
		...
	, context)

, where

  • pb - represents the pipeline builder.
  • PolicyJustCreated - a policy from the PoliNorError library.
  • funcThatUsesServiceProviderToCreatePolicy - Func that uses the IServiceProvider to create a policy.
  • funcThatUsesContextAndServiceProviderToCreatePolicy - Func that uses the IServiceProvider and context to create a policy.
  1. When you want to complete the pipeline, call the AsFinalHandler method for the last added handler and configure HttpErrorFilter to filter transient http errors and/or any non-successful status codes or categories:
services.AddHttpClient<IAskCatService, AskCatService>((sp, config) =>
	{
			...
	})
	.WithResiliencePipeline((pb) => 
		pb
		...
		.AddPolicyHandler(PolicyForFinalHandler)
		//Adds transient http errors to the response handling filter.
		.AsFinalHandler(HttpErrorFilter.HandleTransientHttpErrors())
		...
	)

Additionally, you can include custom failure status codes or categories in the final handler filter:

		...
		.AsFinalHandler(HttpErrorFilter.HandleHttpRequestException()
			//Also adds 5XX status codes to the response handling filter.
			.OrServerError())
		...

You can also include in the filter any exception type thrown by an inner handler:

		...
		.AsFinalHandler(HttpErrorFilter.HandleTransientHttpErrors())
		//Include 'SomeExceptionFromNonPipelineHandler' exceptions in the filter 
		//when thrown by a non-pipeline handler (in this case).
		.IncludeException<SomeExceptionFromNonPipelineHandler>()
		...

  1. In a service that uses HttpClient or HttpClientFactory, wrap the call to HttpClient in a catch block that handles the special HttpPolicyResultException exception. If the request was not successful, examine the HttpPolicyResultException properties in this handler for details of the response:
try
{
	...
	using var response = await _client.GetAsync(uri, token);
	...
}
catch (OperationCanceledException oe)
{
	...
}
catch (HttpPolicyResultException hpre)
{
	//If the response status code matches the handling filter status code:
	if (hpre.HasFailedResponse)
	{
		//For example, log a failed status code.
		logger.LogError("Failed status code: {StatusCode}.", hpre.FailedResponseData.StatusCode);
	}
}
catch (Exception ex)
{
	...
}

πŸ“œ HttpPolicyResultException properties

Public properties of the HttpPolicyResultException:

  • InnerException
    • If the response status code matches the handling filter’s status code, it will be a special FailedHttpResponseException.
    • If no handlers inside or outside the resiliency pipeline throw an exception, and the HttpClient’s primary handler throws an HttpRequestException, the InnerException will be that HttpRequestException.
    • Otherwise, the exception originates from one of the handlers, either inside or outside the pipeline.
  • FailedResponseData - not null if the status code part of the handling filter matches the response status code.
  • HasFailedResponse - true if FailedResponseData is not null.
  • PolicyResult - specifies the PolicyResult<HttpResponseMessage> result that is produced by a policy that belongs to the DelegatingHandler that throws this exception.
  • InnermostPolicyResult - specifies the PolicyResult<HttpResponseMessage> result produced by a policy of the final handler or by a handler in the pipeline that throws its own exception.
  • IsErrorExpected - indicates whether the filter for the original exception was satisfied.
  • IsCanceled - indicates whether the execution was canceled.

Samples

See the samples folder for concrete examples.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.8.0 178 10/20/2025
0.5.0 182 8/10/2025
0.3.0 192 6/15/2025
0.2.0 228 4/22/2025
0.1.1 207 3/12/2025
0.1.0 193 3/12/2025