Y.S
Y.S

Reputation: 1862

How to get the exception from HttpResponseMessage in web API?

I'm trying to implement a custom error handling in web API, and I need to get the exception from the returned HttpResponseMessage.

I've tried to get exception info by from:

response.Content.ReadAsAsync<HttpError>().Result

But I can't access the result object, I'm getting an exception when trying, So I'm obviously doing it wrong.

Can't figure out how to do it, Assistance would be appreciated.

Edit:

My client code is not relevant, it's simply a GET request, server code:

Controller action throws Exception:

if (condition == true)
{
    var response = new HttpResponseMessage(HttpStatusCode.BadRequest)
    {
        Content = new StringContent("Some Exception Related Message"),
        ReasonPhrase = "Some More Info"
    };

    throw new HttpResponseException(response);
}

SendAsync method of my implemented DelegatingHandler gets the response, and this is where I want to get the callstack of the exception that was thrown in the controller action above.

errorDetails = new ResponseErrorDetailsFull
{
    Message = "An error has occurred.",
    ExceptionMessage = response.ReasonPhrase,
    StackTrace = response.Content.ReadAsAsync<HttpError>().Result.StackTrace 
};

Edit #2

Ok, So I found out that if I create a ExceptionFilterAttribute, and Override OnException(), use the attribute on my DelegatingHandler I'm able to access the exception as mentioned in the above code.

Can someone provide an explanation why this is working this way?

Upvotes: 9

Views: 34483

Answers (2)

Vitt&#243;ria Zago
Vitt&#243;ria Zago

Reputation: 106

I found this blog with very good example: http://nodogmablog.bryanhogan.net/2016/07/getting-web-api-exception-details-from-a-httpresponsemessage/

I adopted the code with some updates:

if ((int)response.StatusCode >= 400)
 {
      exceptionResponse = JsonConvert.DeserializeObject<ExceptionResponse>(LogRequisicao.CorpoResposta);
      LogRequisicao.CorpoResposta = exceptionResponse.ToString() ;
      if (exceptionResponse.InnerException != null)
             LogRequisicao.CorpoResposta += "\r\n InnerException: " + exceptionResponse.ToString();
 }

using object:

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; }

        public override String ToString()
        {
            return "Message: " + Message + "\r\n "
                + "ExceptionMessage: " + ExceptionMessage + "\r\n "
                + "ExceptionType: " + ExceptionType + " \r\n "
                + "StackTrace: " + StackTrace + " \r\n ";           
        }  
    }

Upvotes: 1

Raja Nadar
Raja Nadar

Reputation: 9489

To get HttpError in the response content, your server side API code needs to have written an HttpError instance into the response stream.

Only then response.Content.ReadAsAsync<HttpError>().Result would yield that data.

normally, if a server side code throws an exception, the default behavior is an HTTP 500 (Internal Server Error) status code with nothing parseable in the response message.

In case of HTTP 400 (Bad Request) or other such non-500 (non-200) errors, it is customary to send back response data. (either Validation Errors etc.) in that case, you may be able to read the data from the response.

in general for any error scenario, unless your server side API code is not writing a known type into the response, you cannot read it off the response on the caller side.

please post your server side and client side code, for us to help you further.

Upvotes: 4

Related Questions