For .NET 5.0 or later, HttpRequestException returns HttpStatusCode property, and you should be using that instead.
Below is my proposed solution for pre-.NET 5.0. The only flaw is that since the ASP.NET Core framework resource manager is internal to the framework, I cannot directly re-use Microsoft's internationalized message strings, so I'm just using the verbatim English message literal here.
Pros
- Logs the content for an 5xx server error
- Sometimes, a server error is actually a client error in disguise, such as a client using a deprecated endpoint that finally got shut off.
- Makes it easier to uncover errors when writing integration tests using
ConfigureTestContainer<T>
Cons
- Inefficient.
- If you read the response content, and the content is very long, you will slow the client down. For some clients, with soft real-time response requirements, this jitter may be unacceptable.
- Incorrect responsibility for error logging and monitoring.
- If this is a 5xx server error, why does the client care, since the client did nothing wrong? Just call
response.EnsureSuccessStatusCode();
and let the server deal with it.
- Why not just check the server error logs when there is an Internal Server Error?
- Requires reading the
Content
property prior to checking the status. There may be situations where this is not desirable, one of which is inefficiency.
Usage
using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, "controller/action"))
{
using (var response = await HttpClient.SendAsync(requestMessage))
{
var content = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode2(content);
var result = JsonConvert.DeserializeObject<ResponseClass>(content);
}
}
API
public static class HttpResponseMessageExtensions
{
public static void EnsureSuccessStatusCode2(this HttpResponseMessage message, string content = null)
{
if (message.IsSuccessStatusCode)
return;
var contentMessage = string.IsNullOrWhiteSpace(content) ? string.Empty : $"Content: {content}";
throw new HttpRequestException(string.Format(
System.Globalization.CultureInfo.InvariantCulture,
"Response status code does not indicate success: {0} ({1}).{2}",
(int)message.StatusCode,
message.ReasonPhrase,
contentMessage)
);
}
}