Building SharePoint Web Parts – Basic Handling of Exceptions

I’ve gone through the process of creating custom web parts a few dozen times now, and I thought I’d share an exception handling pattern that I’ve found very useful. I keep re-using this pattern for two reasons:

  1. It is REALLY simple.
  2. It works.

If a web part doesn’t handle an exception, SharePoint will catch the exception and display the dreaded generic fault page. Although there are situations where you might want the whole page to fail, most of the time it is a better user experience if the page remains intact and just the custom web part fails. It is possible to avoid the generic fault page by following the standard practice of wrapping every line of code in a try-catch block. I always wrap small, recoverable sections in their own try-catch blocks and then wrap the entire method in a try-catch that handles unrecoverable errors, like this:

private void myMethod()
{
	try
	{
		if (_sUnrecoverableException != null)
			return;

		//Some Code...

		//A simple recoverable exception
		Sprocket sSprocket1;
		try
		{
			sSprocket1 = wWidget1.getSprocket();
		}
		catch(NullReferenceException nreRecoverable)
		{
			//An exception caught here can be recovered from.
			//This is just a sample, you would never use exception handling to
			//catch an uninitiated variable like this.
			wWidget1 = new Widget();
			sSprocket1 = wWidget1.getSprocket(); //We’ve recovered and can continue
		}

		//Some more code...
	}
	catch(Exception eUnrecoverable)
	{
		//Exceptions caught here cannot be recovered from, the webpart needs to
		//gracefully fail.
		_sUnrecoverableException = “myMethod exception: “ + eUnrecoverable.Message;
		//I find messages of the format “MethodName: Exception text” to be very useful
		//during development.  You would replace this text with a user friendly equivalent
		//when making a production build.
		//Here is also where you would write the full exception to the log as well.  You could
		//use code like the following to do so:
		if (!EventLog.SourceExists("MyWebPart"))
			EventLog.CreateEventSource("MyWebpart", "Application");
		EventLog log = new EventLog();
		log.Source = "MyWebPart";
		log.WriteEntry(eUnrecoverable.ToString(), EventLogEntryType.Error);
	}
}

The reference to _sUnrecoverableException is a global variable. It tracks whether an exception occurred and the message to display to the user. It is necessary to use a global variable because it is not possible to directly pass the exception between webpart lifecycle methods. i.e. If the exception occurred during CreateChildControls() it must be stored until it can be dealt with in the Render() method. It is also a good idea to avoid unnecessary processing by checking _sUnrecoverableException at the beginning of all the lifecycle methods.

To handle the exception, in the Render method just place a switch that either displays the normal web part or the error message. It is important that in the code that displays the error message, there is no opportunity for another exception to occur. If an exception does happen at this point, there is nothing that can be done to gracefully handle it, just let SharePoint deal with it and display the generic fault page. Here is an example of what a simple Render method might look like:

protected override void Render(HtmlTextWriter writer)
{
	if (_sUnrecoverableException != null)
	{
		//Display the user friendly error message.  It will be ugly, but is
		//unlikely to throw an exception.
		this.Controls.Clear();
		this.Controls.Add(new LiteralControl(_sUnrecoverableException));
	}
	base.Render(writer);
}

…and that is all there is to this particular pattern.

For further reading, here are the best links I’ve been able to find about exception handling in SharePoint:

http://www.sharepointsecurity.com/sharepoint/sharepoint-development/webpart-exception-handling-standards/

http://msdn.microsoft.com/en-us/library/ff647598.aspx

Advertisements

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

%d bloggers like this: