Calvin
Calvin

Reputation: 1163

HttpClient doesn't report exception returned from web API

I'm using HttpClient to call my MVC 4 web api. In my Web API call, it returns a domain object. If anything goes wrong, a HttpResponseException will be thrown at the server, with a customized message.

 [System.Web.Http.HttpGet]
  public Person Person(string loginName)
    {
        Person person = _profileRepository.GetPersonByEmail(loginName);
        if (person == null)
            throw new HttpResponseException(
      Request.CreateResponse(HttpStatusCode.NotFound, 
                "Person not found by this id: " + id.ToString()));

        return person;
    }

I can see the customized error message in the response body using IE F12. However when I call it using HttpClient, I don't get the customized error message, only the http code. The "ReasonPhrase" is always "Not found" for 404, or "Internal Server Error" for 500 codes.

Any ideas? How do I send back the custom error message from the Web API, while keep the normal return type to be my domain object?

Upvotes: 6

Views: 10513

Answers (3)

Bryan
Bryan

Reputation: 5471

I factored out some of the logic when grabbing the exception from a response.

This makes it very easy to extract the exception, inner exception, inner exception :), etc

public static class HttpResponseMessageExtension
{
    public static async Task<ExceptionResponse> ExceptionResponse(this HttpResponseMessage httpResponseMessage)
    {
        string responseContent = await httpResponseMessage.Content.ReadAsStringAsync();
        ExceptionResponse exceptionResponse = JsonConvert.DeserializeObject<ExceptionResponse>(responseContent);
        return exceptionResponse;
    }
}

public class ExceptionResponse
{
    public string Message { get; set; }
    public string ExceptionMessage { get; set; }
    public string ExceptionType { get; set; }
    public string StackTrace { get; set; }
    public ExceptionResponse InnerException { get; set; }
}

For a full discussion see this blog post.

Upvotes: 2

Calvin
Calvin

Reputation: 1163

(Putting my answer here for better formatting)

Yes I saw it but HttpResponseMessage doesn't have a body property. I figured it out myself: response.Content.ReadAsStringAsync().Result;. The sample code:

public T GetService<T>( string requestUri)
{
    HttpResponseMessage response =  _client.GetAsync(requestUri).Result;
    if( response.IsSuccessStatusCode)
    {
        return response.Content.ReadAsAsync<T>().Result;
    }
    else
    {
        string msg = response.Content.ReadAsStringAsync().Result;
            throw new Exception(msg);
    }
 }

Upvotes: 16

Kiran
Kiran

Reputation: 57949

The custom error message would be in the 'body' of the response.

Upvotes: 0

Related Questions