Verifying the results of an EWS or EWS Managed API call

Learn how to verify the results of your EWS or EWS Managed API calls.

When things aren't working correctly, it helps to see what's going on by examining the SOAP requests that your application is sending over the network and the responses that the server is sending back. The tools and resources for troubleshooting EWS applications article includes links to tools to help capture and view those SOAP requests. After you've got the requests and the responses, how do you verify that the request you sent to the server was processed correctly? Read on to find out.

If you're sending EWS requests, you're going to start your verification by checking the ResponseClass attribute for each response message in the response. That will tell you whether the operation completed successfully on each item.

Depending on the object that your method is calling, if you're using the EWS Managed API to send requests, you can do some verification using the response objects. But because the SOAP response contains a superset of what's included in the EWS Managed API response objects, you might want to look at the SOAP response as well. Because the SOAP response can often contain more information than the EWS Managed API response objects, start your verification with the SOAP response.

Verifying the results of a SOAP response

When you receive a SOAP response, the first thing to look at is the ResponseClass attribute. This attribute is included in each ResponseMessageType instance in the ResponseMessages element, as shown in the following example.

<s:Body>
      <m:GetItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                         xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
        <m:ResponseMessages>
          <m:GetItemResponseMessage ResponseClass="Success">
          …

Because a SOAP response might contain multiple response messages in a single SOAP response, it's important to check each response message individually.

If you're working with an operation that includes a ResponseClass as part of the operation response, like the following, you might be tempted to only check the ResponseClass of the operation.

<soap:Body>
  <m:AddDelegateResponse xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
                         ResponseClass="Success"
                         xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages">
  …

However, the operation status only reflects the shape of the top-level response and does not reflect the status of all the individual message responses. In the following example, the AddDelegateResponse operation has a ResponseClass of Success, but the underlying DelegateUserResponseMessageType element has a ResponseClass value of Error.

<soap:Body>
  <m:AddDelegateResponse xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
                         ResponseClass="Success"
                         xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages">
    <m:ResponseCode>NoError</m:ResponseCode>
    <m:ResponseMessages>
      <m:DelegateUserResponseMessageType ResponseClass="Error">
        <m:MessageText>The user is already a delegate for the mailbox.</m:MessageText>
        <m:ResponseCode>ErrorDelegateAlreadyExists</m:ResponseCode>
        <m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
      </m:DelegateUserResponseMessageType>
    </m:ResponseMessages>
  </m:AddDelegateResponse>
</soap:Body>

So for SOAP EWS responses, you can't rely on the ResponseClass of the operation - you have to look at the ResponseClass of each response message to determine whether the operation encountered any errors processing the items.

Verifying success

If each ResponseClass attribute for each ResponseMessage attribute is set to Success, the operation completed successfully on all the items, and you can move on to your next task.

The following example shows a successful response to a GetItem operation request to retrieve a single item. Note that when the ResponseClass is set to Success, the associated ResponseCode is always set to NoError.

<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <m:GetItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                         xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
        <m:ResponseMessages>
          <m:GetItemResponseMessage ResponseClass="Success">
            <m:ResponseCode>NoError</m:ResponseCode>
            <m:Items>
              <t:Message>
                <t:ItemId Id="Er5bAAA=" 
                          ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAhE0/M" />
                <t:Subject>Dinner Party</t:Subject>
              </t:Message>
            </m:Items>
          </m:GetItemResponseMessage>
        </m:ResponseMessages>
      </m:GetItemResponse>
    </s:Body>

The following is a successful response to a GetItem operation request to retrieve multiple items. Each of the GetItemResponseMessage elements has a ResponseClass of Success.

<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <m:GetItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                     xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
    <m:ResponseMessages>
      <m:GetItemResponseMessage ResponseClass="Success">
        <m:ResponseCode>NoError</m:ResponseCode>
        <m:Items>
          <t:Message>
            <t:ItemId Id="Er5bAAA=" 
                      ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAhE0/M" /
            <t:Subject>Dinner Party</t:Subject>
          </t:Message>
        </m:Items>
      </m:GetItemResponseMessage>
      <m:GetItemResponseMessage ResponseClass="Success">
        <m:ResponseCode>NoError</m:ResponseCode>
        <m:Items>
          <t:Message>
            <t:ItemId Id="3c66AAA="
                      ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAc3kqm" />
            <t:Subject>Company Soccer Team</t:Subject>
          </t:Message>
        </m:Items>
      </m:GetItemResponseMessage>
    </m:ResponseMessages>
  </m:GetItemResponse>
</s:Body>

Handling errors and warnings

When you receive a response and the ResponseClass attribute is set to Error, the operation did not complete successfully on one or more items. Correct the issue and retry your request, or the part of your request that failed. A ResponseClass attribute value of Warning value is only returned by the ResolveNames operation, and indicates that the entity could not be resolved to a unique identity. You can ignore it for all other operations.

In the following response, the ResponseClass attribute has a value of Error.

<m:GetItemResponseMessage ResponseClass="Error">
  <m:MessageText>Property is not valid for this object type.</m:MessageText>
  <m:ResponseCode>ErrorInvalidPropertyRequest</m:ResponseCode>
  <m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
  <m:MessageXml>
    <t:FieldURI FieldURI="meeting:AssociatedCalendarItemId" />
  </m:MessageXml>
  <m:Items />
</m:GetItemResponseMessage>

In this example, EWS provides clues to debug the issue. When the ResponseClass attribute has a value of Error, the following additional elements are included in the response when applicable:

You can use the information provided in these elements to investigate your issue. In the previous example, the MessageText indicates that the property isn't valid for the object type. The request was to get an email message, but the property set included the AssociatedCalendarItemId, which is only valid for appointment items.

The following example shows an error that was received as part of a batched operation to get multiple email items. The first item was retrieved successfully and the ResponseClass is set to Success. The second item could not be found, and the ResponseClass is set to Error.

<m:GetItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                        xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
  <m:ResponseMessages>
    <m:GetItemResponseMessage ResponseClass="Success">
      <m:ResponseCode>NoError</m:ResponseCode>
      <m:Items>
        <t:Message>
          <t:ItemId Id="Er5cAAA="
                    ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAhE0/O" />
          <t:Subject>Business plans</t:Subject>
        </t:Message>
      </m:Items>
    </m:GetItemResponseMessage>
    <m:GetItemResponseMessage ResponseClass="Error">
      <m:MessageText>The specified object was not found in the store.</m:MessageText>
      <m:ResponseCode>ErrorItemNotFound</m:ResponseCode>
      <m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
      <m:Items />
    </m:GetItemResponseMessage>
  </m:ResponseMessages>
</m:GetItemResponse>

When one or more items in a batched request can't be processed as requested, an error is returned for each item that failed, and the rest of the items in the batch are processed as expected. Failures in batch processing can occur if the item was deleted, and therefore can't be sent, retrieved, or updated, or if the item moved to a different folder, and therefore has a new item ID. Because the operation will complete for some items and not return an error when one or more items can't be processed, it's important to check each ResponseClass attribute before you move on to your next operation.

If the information provided by the response elements doesn't help you correct your request or otherwise unblock you, see Next steps.

Verifying the results of an EWS Managed API method call

If you're using the EWS Managed API and calling a method on an ExchangeService object, your method will likely return a ServiceResponseCollection object, which contains a collection of ServiceResponse objects, or a collection of objects derived from the ServiceResponse objects. The ServiceResponseCollection and included ServiceResponse objects contain information about the result of the method call, which you can use to verify your results.

If you're using the EWS Managed API and calling a method on an Item object, or one of the derived objects, the method likely does not return a response object to check for success, but does throw an Exception if the method does not complete successfully.

Verifying success

One benefit of using the EWS Managed API is that it provides an overall status when dealing with multiple items in one response. So if the method you called returns a ServiceResponseCollection, you can check that the OverallResult property of the ServiceResponseCollection is equal to ServiceResult.Success. If so, all the items in the batched process were completed successfully; you don't have to check each ServiceResponse object individually. If the OverallResult property is not set to ServiceResult.Success, you have to handle the error or warning.

If the method you're calling does not return a ServiceResponseCollection, but does return a ServiceResponse object, you have to check the value of the Result property. If the Result value is set to Success, you know the method completed successfully.

If the method you're calling has no return value, there's really no way to check for success via the EWS Managed API. As long as an exception is not thrown, you can assume the method completed successfully. For additional validation, you can also check the SOAP response to verify the results.

Handling errors, warnings, and exceptions

If your EWS Managed API code throws an Exception, you can use the Exception.Message value to determine the source of the error. The Message property contains the contents of the MessageText element in the underlying SOAP response. In addition, if the exception is of type ServiceResponseException object, one of the most common exceptions, you can also retrieve the ErrorCode contained in the underlying SOAP ResponseCode element, and the Response property that identifies the associated ServiceResponse object. The following code shows how to catch and display the contents of a ServiceResponseException.

try
    {
         …
    }
    catch (ServiceResponseException ex)
    {
        Console.WriteLine("Error code: " + ex.ErrorCode);
        Console.WriteLine("Error message: " + ex.Message);
        Console.WriteLine("Response: " + ex.Response);
    }

If the method you called returns a ServiceResponseCollection, and the value of the OverallResult property is equal to Warning or Error, you'll have to loop through each object in the ServiceResponseCollection to find the error. The OverallResult property is set to Warning if at least one response has its Result value set to Warning and all other responses have their Result values set to Success. The OverallResult property is set to Error if at least one response has its Result value set to Error. When the OverallResult is set to Warning or Error, the following properties are set on the ServiceResponse objects as appropriate:

  • ErrorCode — Contains the error code, which can be used to find additional troubleshooting resources.

  • ErrorDetails — Contains details about the error for some ErrorCodes. For example, when the error code is ErrorRecurrenceHasNoOccurrence, the ErrorDetails will contain keys for EffectiveStartDate and EffectiveEndDate.

  • ErrorMessage — Describes the error.

  • ErrorProperties — If available, identifies the properties that caused the error. For example, when the error code is ErrorInvalidPropertyForOperation, ErrorProperties contains the definition of the property that was invalid for the request.

  • Result — Contains Error or Warning when an issue is encountered.

If the information provided by the ServiceResponse properties doesn't provide enough information to correct your method call or unblock you, see Next steps to dig up more information on ErrorCode values.

You can look up additional troubleshooting information in the following topics:

In addition, depending on what you're trying to accomplish in your request, you might find additional helpful information about the error code in the following topics:

See also