Home > OS >  Get a status code from HttpRequestException with netstandard 2.1
Get a status code from HttpRequestException with netstandard 2.1

Time:11-05

I'm having trouble to get a status code from a HttpRequestException on netstandard 2.1 at the catch block. At the .NET Framework there is an extra property "StatusCode", but I can't find any similar for netstandard. Is there any alternative?

Thanks in advance.

I already tried to convert a HttpRequestException into a WebException. Catching a WebException does not trigger the catch.

CodePudding user response:

As already mentioned in comments to your OP, the StatusCode property was introduced in .NET 5 and won't be available in .NetStandard. This means you have to "do it yourself".

You can include the status code value in the existing exception without having to create and maintain a new exception type by leveraging the Data dictionary like this (change the names to your liking):

public static class HttpResponseMessageExtensions
{
    public static void MyEnsureSuccessStatusCode(this HttpResponseMessage httpResponseMessage)
    {
        try
        {
            httpResponseMessage.EnsureSuccessStatusCode();
        }
        catch (HttpRequestException ex) when (ex.SetStatusCode(httpResponseMessage.StatusCode))
        {
            // Intentionally left empty. Will never be reached.
        }
    }
}

public static class HttpRequestExceptionExtensions
{
    private const string StatusCodeKeyName = "StatusCode";

    public static bool SetStatusCode(this HttpRequestException httpRequestException, HttpStatusCode httpStatusCode)
    {
        httpRequestException.Data[StatusCodeKeyName] = httpStatusCode;

        return false;
    }

    public static HttpStatusCode? GetStatusCode(this HttpRequestException httpRequestException)
    {
        return (HttpStatusCode?)httpRequestException.Data[StatusCodeKeyName];
    }
}

Note the usage of an always-false exception filter there. This ensures modifying the original exception doesn't incur severe costs as it retains the original exception as is (it is never "caught" there)

You can then use the new extension instead of the original EnsureSuccessStatusCode to throw the exception:

// grab real response here
var response = default(HttpResponseMessage);
response.MyEnsureSuccessStatusCode();

And you can grab the status code from the exception object using the GetStatusCode extension on whoever is catching the exception upstream.

If you want to make this even more robust, and ensure that you only call GetStatusCode on an exception that was thrown using the custom overload, you can also add a "marker" value in the dictionary to indicate that it was thrown using the extension and act on that (for example, throw an InvalidOperationException saying the method can only be used in conjunction with MyEnsureSuccessStatusCode).

  • Related