Using RestSharp.Portable with IgnoreResponseStatusCode = true

Typically when using RestSharp.Portable, if one has to process API calls which doesn't return results e.g. collection of employees, managers etc, he does it somewhat like this.

public Task GetEmployees()
{
   var restClient = new RestClient {CookieContainer = new CookieContainer()};
   var request = new RestRequest("api/employees", HttpMethod.Get);
   await restClient.Execute(request);
}

By default for the RestClient instance IgnoreResponseStatusCode  property is set to false.

What does that mean?

Practically it means that for anything which is not a Http success status code i.e. not in range 200 to 299, you will get an exception in your async request.

The information about the status code received in the Http call is ONLY available in t.Exception.InnerException.Message. 

But that is not we might want always, like we might want to make some decisions based on the error codes received.
Example: Raising a custom exceptions for Http Status Code 400 or 401.

So as to achieve that one has to set IgnoreResponseStatusCode to true instead.

Doing so you will no more get exceptions for failure status code. Instead they can now get the status somewhat like 

if (response.Result.StatusCode == HttpStatusCode.Unauthorized)
{
 ....
 ....
}

So what's the problem as everything seems perfect.

NO. The real issue comes when your API calls are returning some data like Employees List etc.

This time the RestSharp call looks somewhat like (IgnoreResponseStatusCode is set to true)

public Task<IEnumerable<Employee>> GetEmployees()
{
   var restClient = new RestClient {CookieContainer = new CookieContainer(), IgnoreResponseStatusCode = true};
   var request = new RestRequest("api/employees", HttpMethod.Get);
   var response = await restClient.Execute<IEnumerable<Employee>>(request);
   return response.Data;
}

If the API call results in success everything looks good still, but the problem comes when it is an error condition like 400, 401 etc.

Since this time as we have explicitly mentioned IEnumerable<Employee> for de-serialization RestSharp.Portable fails to de-serialize HttpResponse with error code, hence results in JSon parsing exception.

So how to get rid of it?

Try something like below code instead so as to resolve the issue.

public Task<IEnumerable<Employee>> GetEmployees()
{
   var restClient = new RestClient {CookieContainer = new CookieContainer(), IgnoreResponseStatusCode = true};
   var request = new RestRequest("api/employees", HttpMethod.Get);
   var result = await restClient.Execute(request).ParseReponse<IEnumerable<Employee>>(restClient);
   return result;
}

static class public RestResponseHelper
{
   async public static Task<IRestResponse> ParseReponse(this Task<IRestResponse> response, IRestClient client)
   {
       if (response == null) throw new ArgumentNullException("response");

       await response.ContinueWith(t =>
            {
                if (t.IsFaulted || t.IsCanceled)
                    throw new CustomException(t.Exception.Message);

                if (response.Result.StatusCode.IsSuccess()) return;

                if (response.Result.StatusCode == HttpStatusCode.Unauthorized)
                {
                    throw new UnAuthorizedException(response.Result.StatusDescription); //this is a custom exception
                }

                throw new CustomException(response.Result.StatusDescription);
            });
     
      var handler = client != null ? client.GetHandler(response.Result.ContentType) : null;
      return (handler != null) ? handler.Deserialize<T>(response.Result) : default(T);
   }
}


Comments

Post a Comment

Popular Posts