HttpClient Exception Handling

Topics: Web Api
Jan 3, 2012 at 11:34 AM

Hi,

I have just started using WCF Web API v6 and I am transforming some SOAP based services to REST...I intend to go live soon as all was going ok.

Until I stumbled with exception handling. In SOAP based WCF, I used to wrap any service exceptions inside a WCF FaultException and throw this to the client application which then can use the detailed exception information to diagnose the issue.

How can I implement the same with HttpClient (I am using PostAsync)? I really need to keep the exception handling inside my service the same, I just a need a way for my client application to be able to read the exception information...

Any advise please...

Regards,

Jan 3, 2012 at 11:53 AM

Exposing stacktrace as part of a server error is generally a bad idea and can lead to security issues, but can be a useful thing to enable during development time.  I chose to stick to simple readable error message and log the stacktrace in an error database, with the error sent to client including a unique ref to find the message.  IMO you should try to use the HTTP error codes to communicate what happened and keep the text very short but still have some meaning to help the developer on the other end to debug what went wrong (and if he gets an error log id, he can ask you to look it up).

But regarding how to create errors, you can throw HttpResponseException which is then translated into HTTP error codes and text.
All unhandled exceptions that bubble up in your code are automatically wrapped into one of these exceptions with a HTTP 500 error code.

Example:

throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent("Ticket data missing") });

I then created a HttpErrorHandler that overrides the text in the default HTTP 500, 404 and 405 errors (no HTML blobs please), as well as logging them into a database.

Jan 3, 2012 at 12:05 PM

Thanks for your reply: in my case the communication is between two internal systems so exposing exception info is not an issue...

That being said, I like your idea because I have the identical implementation in SOAP using a Message Inspector. But when I tried your code, I could not catch the exception at the client application. So in the service I threw the exception just like you did, but a try-catch block did not catch the exception at the client side...

Am I missing something?

Thanks,

 

Jan 3, 2012 at 1:10 PM
Edited Jan 3, 2012 at 1:13 PM

There is no exception thrown in the client, you have to inspect the HTTP status codes.  The HttpResponseMessage has a handy "IsSuccessStatusCode" boolean to check though :)

However there are situations where the client can throw exceptions, for example when it cannot connect to the specified address.. so I'd recommend doing both.

Example:

try
{
    response = client.Post(string.Empty, ticketContent);
}
catch (HttpRequestException ex)
{
    if (log.IsErrorEnabled == true)
    {
        log.Error("Error connecting to service + more context info", ex);
    }
 
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.ServiceUnavailable) { Content = new StringContent("Error connecting to service.") });
}

// Check HTTP status on response
if (response.IsSuccessStatusCode == false)
{
    if (log.IsErrorEnabled == true)
    {
        log.Error("Error in reply from service. Response:" + response.StatusCode.ToString() + ", text:" + response.Content.ReadAsString());
    }
 
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.ServiceUnavailable) { Content = new StringContent("Error in reply from service X.") });
}
Jan 3, 2012 at 4:37 PM

Thanks SiggiG,

I will give this a try tomorrow and update this thread...