Exception Handling in SharePoint

I feel like i’m going to be opening a can of worms with this one. I’ve given it a fair bit of thought over time and for this post specifically. I’ve read a lot of guidance around the topic. For the most part, best practice exception handling is reasonably well covered in the ASP.NET space but starts to become a bit murky when you delve into the SharePoint sphere. Some of my own personal preferences clash slightly with other advice that exists and like anything to do with SharePoint, often circumstances may dictate the path you need to take.

As such, I was slightly hesitant to write this post. The reason I have is because exception handling seems to be one of the most poorly implemented (or at least forgotten/ignored) tasks in SharePoint development. It’s also an important task when you factor in user experience, performance and ability to monitor your deployed applications. I’ve seen some shockers; from potential exception-throwing lines of code going unmanaged in web parts which could  bring down the entire page, to swallowed exceptions that you’ll never even know are there. I’ve seen catch (Exception ex) blocks scattered everywhere and try-catch blocks used to control execution flow or used in place of pre-exception checks.

There is a lot of good information out there. MSDN has version-specific editions regarding Handling and Throwing Exceptions. There are some good articles written for .NET in general including Scott Mitchell’s Exception Handling Advice for ASP.NET Web Applications, Daniel Turini’s Exception Handling Best Practices in .NET and Russell Allen’s C# .net Exception Handling Best Practice – As Easy as 1, 2, 3?.

The general consensus tends to boil down to a few rules. Generally, the base exception classes (Exception, ApplicationException) shouldn’t be caught or thrown. Exceptions should only be handled if you can add value to how they’re processed, otherwise they should be allowed to bubble up the chain. Finally, exceptions should be reported so corrective action can be taken if nececssary – preferably using an existing framework such as the Exception Management Application Block.

The question is how these rules and surrounding information can be tweaked to be suitable for SharePoint projects. I’ll structure my comments around this by identifying some general rules and outlining where they’re applicable in a SharePoint context.

1. Never, ever swallow an exception.

Pretty obvious, but the following is a definite no-no.

try
{
    // code
}
catch { }

At the very least the error should be reported using error logging functionality, if not handled sufficiently. I have seen an instance whereby the exception was expected and superfluous to report – I wish I could find it now or even remember why to explain – but if this unlikely case ever occurs it should be properly documented in the code.

2. If you’re going to throw an exception, use throw;

A common piece of code I see goes something along the lines of:

try
{
    // code
}
catch (Exception ex)
{
    throw ex;
}

This is actually quite bad practice. The reasons why were highlighted in some of the links I mentioned earlier, but essentially by doing this you clear the stack trace which is very useful when debugging the exception down the track. You’re better off using the following:

try
{
    // code
}
catch
{
    throw;
}

3. Wherever possible handle the specific exception.

The most common form of exception handling I see is something along the lines of:

try
{
    // code
}
catch (Exception ex)
{
    // handle exception
}

The problem is this goes against the general philosophy behind exception handling. Lee Dumond’s post Friends Don’t Let Friends catch (Exception) explains this nicely.

If you know the object model, or at least know where to go to find the information, you’ll be able to find out which exception/s you should be handling. Take the GetList function in SPWeb. That page identifies clearly the exceptions that may be thrown so you should handle them appropriately.

try
{
    spList = spWeb.GetList("/Path/List");
}
catch (FileNotFoundException ex)
{
    // handle exception
}
catch (ArgumentException ex)
{
    // handle exception
}

An important point to note is that your catch blocks must go in order of most specific to least specific.

4. If you can check for a condition before it throws an exception, do so.

A common block of code you may see is something along the lines of:

try
{
    myString = listItem["MyField"].ToString();
}
catch (Exception ex)
{
    // handle exception
}

Sure, if MyField was never populated in the list item it would throw an exception when you attempt to convert it to a string, but why not check to see if it was populated in the first place?

if (!string.IsNullOrEmpty(listItem["MyField"]))
{
    myString = listItem["MyField"].ToString();
}

5. You got to know when to hold ‘em, know when to fold ‘em.

Ok I may have stretched the poetic licence a bit there. What i’m talking about somewhat contradicts the rule regarding letting exceptions bubble up the chain to be handled at the application level. Consider you have a web part on a page, relatively non-critical to the page or application as a whole, a weather web part for instance. Do you really want the whole page to error out because it generated an exception? I wouldn’t begrudge you a global catch (Exception) in that instance.

On the flip side, imagine an event receiver that is processing a list item that is currently being added. The processing is necessary to complete the step of adding the list item, but the exception is caught, reported and held. The list item will exist, but the process did not complete, and depending on the level of reporting the user may never have a clue.

The point is you really need to use your best judgement when it comes to error handling in SharePoint. It’s hard to state a catch-all rule that can be applied across the board, often it will depend on context.

6. Determine the most appropriate form of logging and use it.

I would have preferred to state how errors should be logged in a SharePoint application much more definitively than this. The most important takeaway is to ensure that the errors are logged. The 2 most logical locations to log the errors would be the ULS or Event Log, however this may not always be appropriate. If these locations aren’t regularly monitored or accessible by the people who need to know about the errors, then it is essentially no better than swallowing the errors in the first place. Email, CRM, a database or even a SharePoint list are other potential locations that could be more accessible. Logging to a file on the file system makes little sense seeing if that is an accessible option you could just use the ULS. I write on this topic in more detail and explain my preference for logging to the ULS/Event Log using the SharePoint Guidance Library in my post Error Logging in SharePoint.

7. Use a custom error page.

Nothing looks worse on a public facing internet site or even an intranet application than when you get the ‘yellow screen of death’. Wherever possible you should display a user friendly message rather than an ugly generic error page. I explain the options available around this topic in my post Custom Error Pages in SharePoint.

That about covers it. Just thinking about this post made my head spin around in circles so it’s no wonder why a vast number of developers take the shortcut route and use global try-catch blocks with generic Exceptions. Hopefully this post sheds some light however on why doing so is a bad idea and that there are better options available to be leveraged. If anyone wishes to comment on the topic I’d be very interested in hearing opposing views and ideas – I’d still consider myself learning the best practice approach to exception handling at this point.

About these ads

6 Responses to Exception Handling in SharePoint

  1. Shilpa Salian says:

    Hi Matt

    Excellent Post. Thanks for sharing your knowledge.

  2. NIck S says:

    Hi Matt,

    In #4:

    String.IsNullOrEmpty(listItem["MyField"]) doesn’t really make sense – listItem is SPListItem and not a String. And as you rightly say in the text, you cannot do a ToString() on a null object.

    So, how to best check for empty list item columns?

    Thanks for the great resource page on SP exceptions – it is often my reference.

    Nick

    • Matt says:

      Hey Nick. We’re not testing SPListItem, we’re testing the MyField property within it (which in this case i’m inferring we know is a string). If you look at the decompiled IsNullOrEmpty function you’ll see that it first checks whether it is null, then checks whether the length is 0. So if the field was not populated and hence came back as null, that line of code would successfully come to that conclusion. You could if you prefer simply check != null instead, I prefer the readability of the IsNullOrEmpty function.

  3. Javier de Hoyos says:

    Hi Matt,

    Thanks for your post, very useful. Please note that in #4 the if condition should be !String.IsNullOrEmpty.

    Javier.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: