SharePoint COM, client side error handling and impact on the performance + tips to handle returned error codes
Hi,
As stated in the title, in this blog post, we're going to see the difference between handling errors client side and server sides when using the SharePoint Client Object Model.
An introduction to this is available on MSDN at http://msdn.microsoft.com/en-us/library/ee534976.aspx and a more detailed documentation is available at http://ranaictiu-technicalblog.blogspot.com/2010/08/sharepoint-2010-exce....
However, none of these describes how to deal with returned errors, nor whether it's more performant or not to use the client side error handling using ExceptionHandlingScope.
So, the main advantage of this client side error handling is that you can from the client decide how the server should react in case an error occurs without calling ExecuteQuery() or ExecuteQueryAsync() multiple times. This avoid unnecessary roundtrips between the client and the server.
However, while this is true, client side error handling doesn't work the same way than server-side error handling. In server-side error handling, we trap the exception details directly in the catch block so that this:

is totally possible. As soon as you are in the catch block, you can start working on the returned error (displaying it, log it, check what kind of error, stack trace etc...)
while in Client Side Error handling, this:
won't throw an error but won't work either. Because, the ServerErrorCode will always be -1. The reason for that is because at that stage, no communication has been done with the server so, that's why you get an empty error code even when an error occurs.
It means that you can't undertake a specific action according to a specific error. In the example shown on MSDN, the only possible error you could have is that the list doesn't exist. So, you know that if you get in the catch block, it's 99,99% due to the fact that the list doesn't exit.
However, when you don't know in advance the type of error you might encounter, this can be kind of a problem and I have no solution for that. But, what I noticed is that you can read the right error code after ExecuteQuery() or ExecuteQueryAsync() was called:
At that stage, the error code is correctly returned. It's a bit shocking to use the scope object outside the using block...but that's the only way to get it working (at least according to what I found).
The other way is not to use using blocks.
Okay, so now that we've seen how to get the error code back if any, what about multiple operations to perform at once? Say you want to delete 100 items of a list no matter whether there are errors or not. It's a kind of "on error continue" mode. How to deal with that?
With the below code:

As soon as an error is met, the server will stop the treatement although the try/catch logic is applied for each operation. It seems that one error only is permitted per scope...:). Here I say that I want to delete the 3 first items of a list. If I put a breakpoint before starting the delete operations, then if I go delete the two first items manually from the SharePoint UI, then I hit F5 to go ahead, my last item won't be deleted, meaning that the server stopped as of the first error encountered.
Moreover, I have only the code returned for this first error of course. So, how to say "I want to delete all the items I can and treat the errors afterwards?". Here is a technique that seems to work:

What is it all about?
- Start initializing a dictionnary that will store all the item ids & scope objects
- foreach delete operation, instanciate a new scope object
- after the loop completes, read your dictionnary and get all the items ids for which the server encountered a problem via a LINQ query.
In my case, I had a list with 3 items, I put a breakpoint before the delete operations, then I removed the two first items but left the third one in the list. Then I just let the program go ahead and here was the ouptut of the program:

So I got indeed the right errors for the right IDS plus my third item was correctly deleted from the list as I expected. Bear in mind that all of this occured with one call to the server only.
What are the drawbacks of this technique:
1) You instanciate a scope object for each operation...so that's of course resource consuming on the client
2) With the client OM, you have to limit your batch size to more or less 300 items, otherwise you get an error from the server telling you that your query was too big.
What's the alternative?
Actually, you can just do this:

Which will produce the same results, meaning that you get the right errors & all the other items are deleted but the major difference is that you contact the server for every item because of the call to ExecuteQuery().
So, what's best? 1 option consumes memory & resources, the 2nd one generates a lof of roundtrips to the server.
Here are a few tests I performed using both techniques.
To delete hundred items, I got these results:

No Client Error Handling == Call to executequery for every item
ClientError Handling == one scope object per operation
What do we see?
On 5 attemps, with the client error handling (1 scope object per operation), each attempt is at least 1 sec faster than with the other approach.
If we do the same with 200 items:

the time difference increases as there are almost 2 secs of difference for each attempt.
Note that the figures obtained with those tests are not representative of a prodution system since I ran them on a development machine with poor resources. But what's important to remember is the time difference between both techniques, not the figures themselves.
Happy Coding!