Wednesday, April 9, 2014

Troubleshooting and error handling - handling exceptions thrown by the DFP API (Part I)

We often get a lot of questions about running into exceptions when using the DFP API and what to do about them. Seeing an exception from time-to-time is a normal part of the API workflow and should be expected. Some exceptions are caused by user errors, others by server issues. We strongly recommend that you write code to handle exceptions early on so that it’s easier to troubleshoot issues when they occur. In this blog post, we’ll go over the first of two major scenarios where adding exception handling will benefit you.

Creating or updating entities

When creating or updating entities with the DFP API, if you forget to supply a required field or set a field to an invalid value, the API throws an ApiException. If you write code to catch this exception, you can print out the error message to show the root cause. The following is an example showing how to do this when using the Google Ads API Java Client Library to create line items.

  // Create a line item.
  LineItem lineItem = new LineItem();
  // lineItem.setSomeThings(...);

  try {
    // Create the line item on the server.
    lineItemService.createLineItems(new LineItem[] {lineItem});
  } catch (ApiException e) {
    ApiError[] apiErrors = e.getErrors();
    for (ApiError apiError : apiErrors) {
      StringBuilder errorMessage = new StringBuilder();
      errorMessage.append(String.format(
          "There was an error of type '%s', on the field '%s',"
          + "caused by an invalid "
          + "value '%s', with the error message '%s'",
          apiError.getApiErrorType(), apiError.getFieldPath(),
          apiError.getTrigger(), apiError.getErrorString()));
      if (apiError instanceof NotNullError) {
        errorMessage.append(String.format(", with the reason '%s'.",
            ((NotNullError) apiError).getReason()));
      } else if (apiError instanceof FrequencyCapError) {
        errorMessage.append(String.format(", with the reason '%s'.",
            ((FrequencyCapError) apiError).getReason()));
      }

      // Append details of other ApiErrors that you are interested in.

      System.err.println(errorMessage.toString());
    }
  }
If you use this code to create a line item, it prints the following if you don’t specify an order ID:
There was an error of type 'NotNullError', on the field 'lineItem[0].orderId',
  caused by an invalid value '', with the error message 'NotNullError.NULL',
  with the reason 'NULL'.
If you provide invalid values for the frequency caps field when creating a line item, you’ll get the following:
There was an error of type 'FrequencyCapError', on the field
  'lineItem[0].frequencyCaps', caused by an invalid value '1000', with the
  error message 'FrequencyCapError.RANGE_LIMIT_EXCEEDED', with the reason
  'RANGE_LIMIT_EXCEEDED'.
There was an error of type 'FrequencyCapError', on the field
  'lineItem[0].frequencyCaps', caused by an invalid value '0', with the error
  message 'FrequencyCapError.IMPRESSIONS_TOO_LOW', with the reason
  'IMPRESSIONS_TOO_LOW'.
Depending on the type of application you’re writing, you may want to show these error messages to your user in a UI or log them. Note that you can find an entity’s required fields and valid field values in our reference documentation, for example, LineItem.

If you’re getting exceptions when creating or updating entities that are not ApiException errors (such as a SERVER_ERROR) and are unclear on how to diagnose them, then you can always write to us on the API forums and include the requestId of the call that failed and we will help you diagnose the issue.

Look forward to part II of this blog post where we will discuss handling exceptions that are thrown when retrieving entities.