Class HttpResponseExtensions
- Namespace
- FunctionalDdd
- Assembly
- FunctionalDdd.Http.dll
Provides extension methods for handling HTTP response messages with Result and Maybe monads.
public static class HttpResponseExtensions
- Inheritance
-
HttpResponseExtensions
- Inherited Members
Examples
Typical usage with Railway Oriented Programming:
var result = await httpClient.GetAsync(url, ct)
.HandleNotFoundAsync(Error.NotFound("User", userId))
.ReadResultFromJsonAsync(UserJsonContext.Default.User, ct)
.TapAsync(user => _logger.LogInformation("Retrieved user: {UserId}", user.Id));
Remarks
These extension methods simplify common patterns when working with HTTP responses in a functional style:
- Error handling for specific status codes (404 Not Found)
- Custom error handling for failed responses
- JSON deserialization with Result<T> and Maybe<T> support
- Fluent composition with Railway Oriented Programming
All methods are designed to integrate seamlessly with functional result types, enabling fluent error handling and composition in asynchronous workflows. The caller is responsible for disposing of the underlying HttpResponseMessage and handling cancellation via CancellationToken where applicable.
Methods
EnsureSuccess(HttpResponseMessage, Func<HttpStatusCode, Error>?)
Ensures the HTTP response has a success status code, otherwise returns an error.
public static Result<HttpResponseMessage> EnsureSuccess(this HttpResponseMessage response, Func<HttpStatusCode, Error>? errorFactory = null)
Parameters
responseHttpResponseMessageThe HTTP response message.
errorFactoryFunc<HttpStatusCode, Error>Optional function to create a custom error based on the status code. If not provided, a default unexpected error will be created.
Returns
Examples
var result = await httpClient.GetAsync(url, ct)
.EnsureSuccessAsync()
.ReadResultFromJsonAsync(jsonContext, ct);
Remarks
This is a functional alternative to HttpResponseMessage.EnsureSuccessStatusCode(), which throws an exception. This method returns a Result instead, making it compatible with Railway Oriented Programming patterns.
EnsureSuccessAsync(Task<HttpResponseMessage>, Func<HttpStatusCode, Error>?)
Ensures the HTTP response has a success status code, otherwise returns an error asynchronously.
public static Task<Result<HttpResponseMessage>> EnsureSuccessAsync(this Task<HttpResponseMessage> responseTask, Func<HttpStatusCode, Error>? errorFactory = null)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
errorFactoryFunc<HttpStatusCode, Error>Optional function to create a custom error based on the status code. If not provided, a default unexpected error will be created.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
HandleClientError(HttpResponseMessage, Func<HttpStatusCode, Error>)
Handles any client error (4xx) status codes with a custom error factory.
public static Result<HttpResponseMessage> HandleClientError(this HttpResponseMessage response, Func<HttpStatusCode, Error> errorFactory)
Parameters
responseHttpResponseMessageThe HTTP response message.
errorFactoryFunc<HttpStatusCode, Error>A function that creates an error based on the status code.
Returns
Examples
var result = await httpClient.GetAsync(url, ct)
.HandleClientErrorAsync(code => Error.BadRequest($"Client error: {code}"))
.ReadResultFromJsonAsync(jsonContext, ct);
Remarks
This method intercepts HTTP responses with status codes in the 400-499 range. Use this when you want to handle all client errors uniformly, or when you need to create context-specific errors based on the actual status code received.
HandleClientErrorAsync(Task<HttpResponseMessage>, Func<HttpStatusCode, Error>)
Handles any client error (4xx) status codes with a custom error factory asynchronously.
public static Task<Result<HttpResponseMessage>> HandleClientErrorAsync(this Task<HttpResponseMessage> responseTask, Func<HttpStatusCode, Error> errorFactory)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
errorFactoryFunc<HttpStatusCode, Error>A function that creates an error based on the status code.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
HandleConflict(HttpResponseMessage, ConflictError)
Handles the case when the HTTP response has a status code of Conflict (409).
public static Result<HttpResponseMessage> HandleConflict(this HttpResponseMessage response, ConflictError conflictError)
Parameters
responseHttpResponseMessageThe HTTP response message.
conflictErrorConflictErrorThe error to return if the response has a status code of Conflict.
Returns
HandleConflictAsync(Task<HttpResponseMessage>, ConflictError)
Handles the case when the HTTP response has a status code of Conflict (409) asynchronously.
public static Task<Result<HttpResponseMessage>> HandleConflictAsync(this Task<HttpResponseMessage> responseTask, ConflictError conflictError)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
conflictErrorConflictErrorThe error to return if the response has a status code of Conflict.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
HandleFailureAsync<TContext>(HttpResponseMessage, Func<HttpResponseMessage, TContext, CancellationToken, Task<Error>>, TContext, CancellationToken)
Handles the case when the HTTP response is not successful.
public static Task<Result<HttpResponseMessage>> HandleFailureAsync<TContext>(this HttpResponseMessage response, Func<HttpResponseMessage, TContext, CancellationToken, Task<Error>> callbackFailedStatusCode, TContext context, CancellationToken cancellationToken)
Parameters
responseHttpResponseMessageThe HTTP response message.
callbackFailedStatusCodeFunc<HttpResponseMessage, TContext, CancellationToken, Task<Error>>The callback function to handle the failed status code.
contextTContextThe context object.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
Type Parameters
TContextThe type of the context object.
HandleFailureAsync<TContext>(Task<HttpResponseMessage>, Func<HttpResponseMessage, TContext, CancellationToken, Task<Error>>, TContext, CancellationToken)
Handles the case when the HTTP response is not successful asynchronously.
public static Task<Result<HttpResponseMessage>> HandleFailureAsync<TContext>(this Task<HttpResponseMessage> responseTask, Func<HttpResponseMessage, TContext, CancellationToken, Task<Error>> callbackFailedStatusCode, TContext context, CancellationToken cancellationToken)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
callbackFailedStatusCodeFunc<HttpResponseMessage, TContext, CancellationToken, Task<Error>>The callback function to handle the failed status code.
contextTContextThe context object.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
Type Parameters
TContextThe type of the context object.
HandleForbidden(HttpResponseMessage, ForbiddenError)
Handles the case when the HTTP response has a status code of Forbidden (403).
public static Result<HttpResponseMessage> HandleForbidden(this HttpResponseMessage response, ForbiddenError forbiddenError)
Parameters
responseHttpResponseMessageThe HTTP response message.
forbiddenErrorForbiddenErrorThe error to return if the response has a status code of Forbidden.
Returns
HandleForbiddenAsync(Task<HttpResponseMessage>, ForbiddenError)
Handles the case when the HTTP response has a status code of Forbidden (403) asynchronously.
public static Task<Result<HttpResponseMessage>> HandleForbiddenAsync(this Task<HttpResponseMessage> responseTask, ForbiddenError forbiddenError)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
forbiddenErrorForbiddenErrorThe error to return if the response has a status code of Forbidden.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
HandleNotFound(HttpResponseMessage, NotFoundError)
Handles the case when the HTTP response has a status code of NotFound.
public static Result<HttpResponseMessage> HandleNotFound(this HttpResponseMessage response, NotFoundError notFoundError)
Parameters
responseHttpResponseMessageThe HTTP response message.
notFoundErrorNotFoundErrorThe error to return if the response has a status code of NotFound.
Returns
HandleNotFoundAsync(Task<HttpResponseMessage>, NotFoundError)
Handles the case when the HTTP response has a status code of NotFound asynchronously.
public static Task<Result<HttpResponseMessage>> HandleNotFoundAsync(this Task<HttpResponseMessage> responseTask, NotFoundError notFoundError)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
notFoundErrorNotFoundErrorThe error to return if the response has a status code of NotFound.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
HandleServerError(HttpResponseMessage, Func<HttpStatusCode, Error>)
Handles any server error (5xx) status codes with a custom error factory.
public static Result<HttpResponseMessage> HandleServerError(this HttpResponseMessage response, Func<HttpStatusCode, Error> errorFactory)
Parameters
responseHttpResponseMessageThe HTTP response message.
errorFactoryFunc<HttpStatusCode, Error>A function that creates an error based on the status code.
Returns
Examples
var result = await httpClient.GetAsync(url, ct)
.HandleServerErrorAsync(code => Error.ServiceUnavailable($"Server error: {code}"))
.ReadResultFromJsonAsync(jsonContext, ct);
Remarks
This method intercepts HTTP responses with status codes in the 500-599 range. Use this when you want to handle all server errors uniformly, such as for retry logic or fallback mechanisms.
HandleServerErrorAsync(Task<HttpResponseMessage>, Func<HttpStatusCode, Error>)
Handles any server error (5xx) status codes with a custom error factory asynchronously.
public static Task<Result<HttpResponseMessage>> HandleServerErrorAsync(this Task<HttpResponseMessage> responseTask, Func<HttpStatusCode, Error> errorFactory)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
errorFactoryFunc<HttpStatusCode, Error>A function that creates an error based on the status code.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
HandleUnauthorized(HttpResponseMessage, UnauthorizedError)
Handles the case when the HTTP response has a status code of Unauthorized (401).
public static Result<HttpResponseMessage> HandleUnauthorized(this HttpResponseMessage response, UnauthorizedError unauthorizedError)
Parameters
responseHttpResponseMessageThe HTTP response message.
unauthorizedErrorUnauthorizedErrorThe error to return if the response has a status code of Unauthorized.
Returns
HandleUnauthorizedAsync(Task<HttpResponseMessage>, UnauthorizedError)
Handles the case when the HTTP response has a status code of Unauthorized (401) asynchronously.
public static Task<Result<HttpResponseMessage>> HandleUnauthorizedAsync(this Task<HttpResponseMessage> responseTask, UnauthorizedError unauthorizedError)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
unauthorizedErrorUnauthorizedErrorThe error to return if the response has a status code of Unauthorized.
Returns
- Task<Result<HttpResponseMessage>>
A Task<TResult> of Result<TValue> containing the HttpResponseMessage.
ReadResultFromJsonAsync<TValue>(Result<HttpResponseMessage>, JsonTypeInfo<TValue>, CancellationToken)
Reads the HTTP response content as JSON and deserializes it to the specified type using the Result monad.
public static Task<Result<TValue>> ReadResultFromJsonAsync<TValue>(this Result<HttpResponseMessage> response, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken)
Parameters
responseResult<HttpResponseMessage>The Result object containing the HTTP response message.
jsonTypeInfoJsonTypeInfo<TValue>The JSON type information for deserialization.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<TValue>>
A Task<TResult> of Result<TValue> containing the deserialized value.
Type Parameters
TValueThe type to deserialize the JSON content to.
ReadResultFromJsonAsync<TValue>(HttpResponseMessage, JsonTypeInfo<TValue>, CancellationToken)
Reads the HTTP response content as JSON and deserializes it to the specified type.
public static Task<Result<TValue>> ReadResultFromJsonAsync<TValue>(this HttpResponseMessage response, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken)
Parameters
responseHttpResponseMessageThe HTTP response message.
jsonTypeInfoJsonTypeInfo<TValue>The JSON type information for deserialization.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<TValue>>
A Task<TResult> of Result<TValue> containing the deserialized value.
Type Parameters
TValueThe type to deserialize the JSON content to.
ReadResultFromJsonAsync<TValue>(Task<Result<HttpResponseMessage>>, JsonTypeInfo<TValue>, CancellationToken)
Reads the HTTP response content as JSON and deserializes it to the specified type using the Result monad asynchronously.
public static Task<Result<TValue>> ReadResultFromJsonAsync<TValue>(this Task<Result<HttpResponseMessage>> responseTask, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken)
Parameters
responseTaskTask<Result<HttpResponseMessage>>The task representing the Result object containing the HTTP response message.
jsonTypeInfoJsonTypeInfo<TValue>The JSON type information for deserialization.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<TValue>>
A Task<TResult> of Result<TValue> containing the deserialized value.
Type Parameters
TValueThe type to deserialize the JSON content to.
ReadResultFromJsonAsync<TValue>(Task<HttpResponseMessage>, JsonTypeInfo<TValue>, CancellationToken)
Reads the HTTP response content as JSON and deserializes it to the specified type asynchronously.
public static Task<Result<TValue>> ReadResultFromJsonAsync<TValue>(this Task<HttpResponseMessage> responseTask, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
jsonTypeInfoJsonTypeInfo<TValue>The JSON type information for deserialization.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<TValue>>
A Task<TResult> of Result<TValue> containing the deserialized value.
Type Parameters
TValueThe type to deserialize the JSON content to.
ReadResultMaybeFromJsonAsync<TValue>(Result<HttpResponseMessage>, JsonTypeInfo<TValue>, CancellationToken)
Reads the HTTP response content as JSON and deserializes it to the specified type using the Maybe monad and the Result monad.
public static Task<Result<Maybe<TValue>>> ReadResultMaybeFromJsonAsync<TValue>(this Result<HttpResponseMessage> response, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken)
Parameters
responseResult<HttpResponseMessage>The Result object containing the HTTP response message.
jsonTypeInfoJsonTypeInfo<TValue>The JSON type information for deserialization.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<Maybe<TValue>>>
A Task<TResult> of Result<TValue> containing Maybe<T>.
Type Parameters
TValueThe type to deserialize the JSON content to.
ReadResultMaybeFromJsonAsync<TValue>(HttpResponseMessage, JsonTypeInfo<TValue>, CancellationToken)
Reads the HTTP response content as JSON and deserializes it to the specified type using the Maybe monad.
public static Task<Result<Maybe<TValue>>> ReadResultMaybeFromJsonAsync<TValue>(this HttpResponseMessage response, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken)
Parameters
responseHttpResponseMessageThe HTTP response message.
jsonTypeInfoJsonTypeInfo<TValue>The JSON type information for deserialization.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<Maybe<TValue>>>
A Task<TResult> of Result<TValue> containing Maybe<T>.
Type Parameters
TValueThe type to deserialize the JSON content to.
ReadResultMaybeFromJsonAsync<TValue>(Task<Result<HttpResponseMessage>>, JsonTypeInfo<TValue>, CancellationToken)
Reads the HTTP response content as JSON and deserializes it to the specified type using the Maybe monad and the Result monad asynchronously.
public static Task<Result<Maybe<TValue>>> ReadResultMaybeFromJsonAsync<TValue>(this Task<Result<HttpResponseMessage>> responseTask, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken)
Parameters
responseTaskTask<Result<HttpResponseMessage>>The task representing the Result object containing the HTTP response message.
jsonTypeInfoJsonTypeInfo<TValue>The JSON type information for deserialization.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<Maybe<TValue>>>
A Task<TResult> of Result<TValue> containing Maybe<T>.
Type Parameters
TValueThe type to deserialize the JSON content to.
ReadResultMaybeFromJsonAsync<TValue>(Task<HttpResponseMessage>, JsonTypeInfo<TValue>, CancellationToken)
Reads the HTTP response content as JSON and deserializes it to the specified type using the Maybe monad asynchronously.
public static Task<Result<Maybe<TValue>>> ReadResultMaybeFromJsonAsync<TValue>(this Task<HttpResponseMessage> responseTask, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken)
Parameters
responseTaskTask<HttpResponseMessage>The task representing the HTTP response message.
jsonTypeInfoJsonTypeInfo<TValue>The JSON type information for deserialization.
cancellationTokenCancellationTokenThe cancellation token.
Returns
- Task<Result<Maybe<TValue>>>
A Task<TResult> of Result<TValue> containing Maybe<T>.
Type Parameters
TValueThe type to deserialize the JSON content to.