Index for the series:
Exchange ActiveSync Building Blocks – Intro
If you’ve followed the past couple of articles you’ll no doubt have noticed I haven’t gone out of my way to handle exceptions and errors gracefully. If you run into a problem when running the sample code against an Exchange that for some reason is configured differently than mine, (also known as entirely wrong by definition), you might run into the very helpful “Something happened” message without further explanation.
One might be tempted to ask if it’s because I’m lazy, or simply do not know how to handle it. Well, ask no more, because I now intend to do something about it 🙂
There are two main things we need to be able to handle;
– Exceptions (conditions throwing errors).
– ActiveSync protocol errors (usually included as a status code in wbxml returned from the server).
Exceptions can be anything really – HTTP errors, SSL exceptions, network issues. Unless it’s something really obvious like the user entering an incorrect address to the Exchange Server it’s often something that needs to be resolved by the network and/or Exchange admin. If you as a programmer are not able to fix this, (let’s face it, if you’re implementing an ActiveSync client other people will be using with their servers odds are you can’t), you should make sure that the user receives an understandable feedback, and preferably something he can pass along to his helpdesk for resolving. Far too often I run into ActiveSync clients presenting entirely generic error messages that don’t provide me with anything I can work with. I hate it when that happens, and send evil thoughts in the general direction of the programmer who implemented this kind of error handling.
ActiveSync protocol errors are a different beast. These usually happen in the actual ActiveSync traffic, and this means that you are communicating with an Exchange Server, but not necessarily per protocol. This means that it has the potential for being more tricky to troubleshoot, and is more likely to be something the programmer needs to handle. Note that a status code isn’t by definition an error, it can be informational in its nature. Whether it’s an error condition or a generic feedback you should handle it in a proper manner.
I am of course not able to cover every possible error situation that may occur, but I have figured out a few of them that are relevant to troubleshooting 🙂
I’ve separated these into two methods, as it would just create too much work maintaining it across all the different tests I’ve implemented so far if I was inlining it in the test itself. (That these tests themselves might/should be collected in a smaller number of methods is an entirely different matter. All in due time.) Not all errors are valid for all tests, but they usually don’t indicate entirely different things so it shouldn’t matter. You can run into differences between Exchange Server versions – for instance Exchange 2007 will throw an exception (HTTP 449) when you should provision whereas Exchange 2010 returns this as a status code (141/142) instead. I’ve added a few checks to my code for this, but if you want to make sure your code works across Exchange versions you need to study the MSDN docs good and make note of all change log entries between the versions.
I’m reusing the UI from the FolderSync test app (EAS_BB_Part-02_03), but behind the scenes I have added the code required to provide the user with a little bit more information if something fails.
Please note that while I have previously included a code snippet in all apps so that all certificates are happily accepted, I have removed these lines specifically to be able to throw such SSL error conditions. (You have the source so modify it if you don’t like this behavior.)
The first method is for parsing the HTTP errors (throws WebExceptions). There’s lines that seem to be cut off below – it’s just for illustrative purposes. Use the code from the source file; don’t copy & paste from the box below.
For parsing the status codes out of the returned wbxml we actually cheat a little bit. We just check if the wbxml contains these codes statically. Which means that if you have a folder called for instance “142” this could be misinterpreted as an error. Where we are presently with our little program this doesn’t really matter, but it will make sense to implement it properly if you’re doing actual synchronization. (We haven’t covered wbxml yet either, so it wouldn’t make sense at any rate now.)
We should then proceed to replace this catch:
With the more suitable:
To handle status codes in an actual response from the server we should add a line to the output code to parse out the status.
To be sure I would get an error I made a small edit to my ActiveSync mailbox policy. Last time we made sure to allow non-provisionable devices, but this time around we’ll make sure of the opposite:
Since we’re not doing any provisioning related activities this should fail.
Lo and behold – we do get an indication as to what our sync problem is (status code 141):
The tip given that I should check “Provisionable device” is a reference to the fact that I’ve copied this code from my EAS MD utility which has such a check box We don’t have such a box yet, but will of course look into that later on.
Certainly not an exciting post this time around, but it was inevitable that I had to implement something more advanced than empty try-catch clauses sooner rather than later. And it makes it easier for you to debug your development environment as well