ServiceStack/ServiceStack — pull request #423 by AndiDog (2013-01-26 15:08:49+00:00)
Title: Allow overriding ServiceClientBase.HandleResponseException and use .ThrowWebServiceException to handle custom error responses

Solves issue #412

Now one can create a custom service client base class and always handle error responses in the same way which is especially helpful if you want to use your own ErrorResponse class. Rough example:

```c#
public sealed class CustomJsonServiceClient : JsonServiceClient
{
[...]

protected override bool HandleResponseException(Exception ex, object request, string requestUri,
Func createWebRequest, Func getResponse, out TResponse response)
{
if(ex is System.Net.WebException && typeof(MyOwnErrorResponse).IsAssignableFrom(typeof(TResponse)))
{
var webEx = (System.Net.WebException)ex;

if(webEx.Status == WebExceptionStatus.ProtocolError)
{
var errorResponse = (HttpWebResponse)webEx.Response;

// Let's say we want to catch HTTP 403 only. Transform System.Net.WebException into ServiceStack
// WebServiceException in order to parse the response and handle the WebServiceException in Send<>'s
// catch statement
if(errorResponse.StatusCode == HttpStatusCode.Forbidden)
{
// Always throws!
ThrowWebServiceException(ex, requestUri);
}
}
}

// Handle other cases as usual
return base.HandleResponseException(ex, request, requestUri, createWebRequest, getResponse, out response);
}

public override TResponse Send(string httpMethod, string relativeOrAbsoluteUrl, object request)
{
try
{
return base.Send(httpMethod, relativeOrAbsoluteUrl, request);
}
catch(WebServiceException e)
{
// If the DTO class was derived from MyOwnErrorResponse, ServiceStack's
// ServiceClientBase.HandleResponseException is able to deserialize the MyOwnErrorResponse properties from
// the message.
if(e.ResponseDto is MyOwnErrorResponse)
{
var errorResponse = (MyOwnErrorResponse)e.ResponseDto;

// here you can throw custom exceptions based on MyOwnErrorResponse properties
}

throw;
}
}

// If you use this Send<> method signature, you also need to override it accordingly:
//public override TResponse Send(object request) { ... }
}
```