Building integrations with Exchange ActiveSync and Exchange Web Services leaves developers feeling a little like this:
At Nylas, we’re uniquely familiar with addressing Microsoft Exchange issues across Exchange email, calendar, and contacts. We’ve built a suite of universal communications APIs that processes billions of requests per day, powering data sync and CRUD in our customers’ applications.
Today, as our San Francisco, Denver, and NYC teams work from home for the sixth week straight, we thought it might be fun to come together and take a look at some of our favorite obscure Exchange edge cases and bugs we’ve encountered along the way.
ActiveSync and Exchange Web Services Documentation
EAS, the proprietary Exchange protocol, has been used by everyone from lone developers to multinational corporations, all navigating the Exchange labyrinth. The challenge might be a fundamental one – for example, EAS syncs either historical data or the most recent changes. How to get both sets of data and not let anything go missing along the way? Or maybe the challenge is a specific edge case that you only stumble upon after hours and hours of trial and error.
The most recent EAS update came in June 2019 and spanned over 500 pages, making it easy to miss updates that introduce breaking changes to your application.
Exchange ActiveSync Introduces WBXML Syntax Updates
When rules to WBXML syntax were updated between versions, it would’ve broken your connection to the Exchange service overnight. Take a look at this WBXML document that works on Exchange servers released after version 14.0:
In Exchange versions 2.5 to 12.1, sending the same data resulted in a different response. In order for this to work in Exchange versions 2.5 to 12.1, the order would have to be rearranged as follows:
Discrepancies in Exchange Web Services Documentation
Even if spelunking through hundreds of pages of documentation is what you like to do best, there can be times when the Exchange documentation contradicts itself with information found elsewhere. Let’s take a look at one such case our team unearthed:
When it comes to routing an Exchange message, the RoutingType field is an important one, defining the routing that is used for the mailbox. According to Exchange docs, this field’s only valid value is ‘SMTP’ and it is set as such by default. However, thorough research revealed that elsewhere in Exchange WebService’s gargantuan collection of documentation, example code features RoutingType ‘EX’, a decidedly non-SMTP value. Perplexing!
This is a good and not uncommon example of how even referencing the documentation isn’t a surefire way to know what you’re doing is correct; you can build according to the specifications and then find yourself trying to figure out why something you built according to the instructions isn’t working.
Exchange Servers Throttling Requests
Sometimes, the Exchange server will throttle your request; this presents several dilemmas. First, because throttling policies vary significantly from Exchange server to server, the configuration of each server also varies, making it necessary to figure out, then ascertain the correct configuration for your particular server.
Second, the response from the Exchange server may tell you to try your request again after n seconds, but because the response doesn’t clearly explain the limitations, you’re left to play a guessing game that involves how to maximize requests while staying under the throttling threshold. Our engineering team’s familiarity with the Exchange protocol can help you navigate the nuances of these scenarios, which you can check out in our detailed developer’s guide.
Another puzzling entry into the annals of Exchange oddities includes calendar events and a bit of time travel. Our engineering team discovered that the Exchange server was sending back XML that set the LastResponseTime of Attendees with a year of 1.
We use the Python time method strftime() in our code which returns a string representing the date specified by the format argument. However, this method does not support the string conversion for datetimes with a year that is earlier than 1900 and any such datetimes would throw a ValueError. In order to address this, we called strftime() on datetimes but if we were returned a ValueError, we manually turned the datetime into a string.
A Better Way to Integrate with Exchange ActiveSync & Exchange Web Services
Building an Exchange integration on your own would take around 17,922 hours. With Nylas, it takes as little as 18 days to build a full email, calendar, and contacts integration to every email service provider. Create a developer account and sync up to 10 accounts for free today.