Search code examples
c#restful-urlbad-requestresponse-headersflurl

Flurl Client - Is it possible to access the headers from a failed request?


I am using Flurl Client to call a restful API with a post data. There is a validation performed on the server on the data I submit and it returns back a header containing an error message for the user.

As the request requirement doesn't satisfy server marks the request as 400 BadRequest. In the below code on line cli.Request(uri).PostJsonAsync(data) it throws the FlurlHttpException with appropriate status code.

Now, as there is a problem with the input data by the user I want to report the user back with the error message which I receive from the server in the header. However, I am unable to access the response headers as the request has failed.

Is there any other way to access the response headers from a failed request using Flurl?

  try
  {
    using (var cli = new FlurlClient(baseUrl))
    {
        var httpResponse = await cli.Request(uri).PostJsonAsync(data);
        var errorMessage = httpResponse.GetHeaderValue("errorMessage");
    }
  }
  catch (FlurlHttpException ex)
  {
  }

Solution

  • Using an event handler works, but I think those are better for cross-cutting concerns like logging that you don't want cluttering the main flow of your app. You basically want to allow and/or handle 400 responses as part of that main flow. You can do that more directly with AllowHtttpStatus, which can be set on the client:

    cli.AllowHtttpStatus(HttpStatusCode.BadRequest);
    

    or the request:

    var httpResponse = await cli
        .Request(uri)
        .AllowHttpStatus(HttpStatusCode.BadRequest)
        .PostJsonAsync(data);
    

    Either way, the call will not throw on a 400.

    Another way to do this, and one I'd recommend if your app logic takes a completely different path on an error condition than on a success condition, is to keep your try/catch in place and use the Response property of the exception to handle the error condition:

    try
    {
        await cli.Request(uri).PostJsonAsync(data);
        // handle success condition
    }
    catch (FlurlHttpException ex) when (ex.Response?.StatusCode == 400)
    {
        var errorMessage = ex.Response.GetHeaderValue("errorMessage");
        // handle error condition
    }
    

    As a side note, there are some significant changes coming in 3.0 that you should be aware of as they touch on some of these areas directly:

    https://github.com/tmenier/Flurl/issues/354

    https://github.com/tmenier/Flurl/issues/488