Friday, October 22, 2010

Handling Errors with the Advantage Web API

The one thing that I didn't discuss in my previous post was how to handle errors returned from an Advantage Web API request. If an error occurs when making a request the error information is packaged up as a JSON response just like a successful data request. Therefore, errors can be handled using classes just like we did with data results.

Below is a sample error response received from a request to the Web API:

{
  "error": {
    "code": "7200",
    "message": {
      "lang": "en-US",
      "value": "Error 7200:  AQE Error:  State = HY000;   NativeError = 5004;  [iAnywhere Solutions][Advantage SQL][ASA] Error 5004:  Either ACE could not find the specified file, or you do not have sufficient rights to access the file. Table name: SomeTable"
    }
  }
}

Instead of the results array we received with a successful request we are now getting error information. So we need to create classes for the serializer to load the information into. The error object defined in the JSON includes a code and a message object. Therefore we will need two classes to handle an error.

// processes the error tag
public class oError
{
  public string code;
  public oErrorMessage message;
}

// processes the message tag
public class oErrorMessage
{
  public string lang;
  public string value;
}

Finally we will need to add this new error object to the oDataResult class so it can be processed. This allows us to process the JSON once checking for either results or an error. You will need to set the MissingMemberHandling property to ignore otherwise an error would occur during deserialization. So our oDataResult class contains three items.

public class oDataResults  // T needs to be a list of objects
{
  public DInfo d;
  public oError error;
  public oQueryMeta __metadata;
}

Now when we make a request we can check for an error before using the list of results.

using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
  using (Stream dataStream = response.GetResponseStream())
  {
    using (StreamReader reader = new StreamReader(dataStream))
    {
      JsonSerializer serializer = new JsonSerializer();
      serializer.MissingMemberHandling = MissingMemberHandling.Ignore;

      oDataResults olist;
      olist = (oDataResults)serializer.Deserialize(
               new JsonTextReader(reader),
               typeof(oDataResults));

      // Check for any errors
      if (olist.error == null)
        dgTable.DataSource = olist.d.results;
      else
        MessageBox.Show(olist.error.message.value);
    }
  }
}

No comments: