sharepoint guidance v2 – drop 8

Last Friday, we’ve released drop 8 of our Guidance.

 

What did we tackle in iteration 8

The main theme in drop 8 was exception handling in SharePoint. But we also did a bunch of refactoring in the application:

  • Service locator
    We want to create a true service locator for sharepoint. However, this is a bit lower on our priority list. So for now we have the interface in place and will keep refactoring it in future drops.
  • Ajax support feature
    We already had an feature that allowed you to add Ajax support to your page. We’ve now cleaned up the code a bit more.
  • LOB Services support
    Created LOB Service Support project to deploy web.config modifications required for LOB services

Exception handling

We looked at a bunch of exception handling scenario’s and how they relate to SharePoint.

The general guidance around exception handling still applies to programming in SharePoint. For example:

  • Use exceptions for exceptional situations. Avoid using error codes to signify error conditions.
  • Use specific exception types. Avoid throwing and catching Exception directly like the plague.
  • Only catch exceptions that you can handle.
  • Never ever EVER EVER catch(Exception ex) and swallow it! This can result in bugs that are almost impossible to find! The ONLY place where you can do this, is in an unhandled exception handler where you should:
    • Log the exception
    • Show the user a friendly message: “We’re so sorry, but something went wrong. Please try again later.” or something.
    • Let the application die gracefully.

But please do read the general guidance with regards to exception handling. It’s a good read :)

 

Exception handling in SharePoint

It’s common to have different exception handling strategies for different places in your application. For example, in your web services, you’ll typically apply exception shielding, where you would log the original exception and replace it with a generic error message. An other example would be in your UI, where you would want to log the exception and display a message to a user.

We looked at a couple of these strategies for exceptionhandling in SharePoint where we can apply additional guidance or help. We’ve looked at exception handling in:

  • Pages
    Exception handling in pages in sharepoint is not very different from exception handling in normal ASP.Net, so there is not that much we can provide Sharepoint specific guidance on.
  • Webparts and usercontrols
    Technically, exception handling in webparts and usercontrols in SharePoint is not very differnet from exception handling in asp.net. However, since end-users can create their own pages by dragging several webparts on a page, you often don’t want a single webpart to take down the whole page. So we’ve built an Exception Handling stragety for webparts.
  • ListItemEventReceiver
    If an unhandled exception occurs in a ListItemEventReceiver, what you typically want to do is cancel the action and set the error message. However, if you forget to cancel the action, the change will still continue, which can cause all sorts of problems.  So we’ve built an exception handling stragety for ListItemEventReceivers.
  • Workflows
    It’s pretty easy to implement exception handling in workflows, so we haven’t built anything for it. We’ll probably add some guidelines in our guidance though.

Exceptionhandling in webparts and usercontrols

The default behavior of an unhandled exception in a web part is that the exception will bubble up to the page. There asp.net will redirect to an error page. Since SharePoint allows you to dynamically create pages and add some webparts to them, you might not want a single webpart to take down the whole page. So we’ve built something to allow you to do just that.

We typically apply the Model – View – Presenter pattern to webpart development, because that allows us to easily unit test our UI logic. This pattern looks like this:

image

The webpart loads up a view (an UserControl, to allow for the design time experience). The View loads up a presenter that holds all the UI logic and only communicates to the presenter using a interface (so we can mock out the view during while testing).

So how would we create an exceptionhandler for the webparts that can show error messages? The easiest approach is to allow the view to render error messages:

image

So our Presenter uses an ExceptionHandler to log and show exception messages. However, the (generic) Exceptionhandler needs some mechanism to display error messages. In this case, our view is the only thing our presenter knows. So we gave the view a special interface, the IErrorVisualizer interface, that the ExceptionHandler can use to display the correct error mesage.

You might not want to make the view responsible for showing 'fatal’ error messages. For one reason, makes the view more complicated. Another reason might be, that you would want a consistent way of displaying error messages across all your webparts. In that case, the following pattern might be better:

image

In this case, we’ve created an error visualizer. It’s just a control that knows how to display error messages. It implements the IErrorVisualizer interface. This way, the view is blissfully unaware on how errors are being displayed.

Now, if the presenter wants to call the error message, it not only needs a reference to the IMyView, but also to the IErrorVisualizer.

This is what the code from the presenter looks like:

    1: public void LoadProduct(string sku)
    2: {
    3:     try
    4:     {
    5:         logger.LogDiagnostic("In OnViewLoaded.");
    6:  
    7:         Product product = productCatalogRepository.GetProductBySku(sku);
    8:  
    9:         if (product == null || product.Sku == null)
   10:         {
   11:             // Show an error message to the user
   12:             new ViewExceptionHandler().ShowFunctionalErrorMessage("Could not find product information.", this.ErrorVisualizer);
   13:         }
   14:         else
   15:         {
   16:             this.view.Product = product;
   17:             this.view.DataBind();
   18:         }
   19:     }
   20:     catch(Exception ex)
   21:     {
   22:         // If something goes wrong, make sure the error gets logged
   23:         // and a non technical message is displayed to the user
   24:         new ViewExceptionHandler().HandleViewException(ex, this.ErrorVisualizer, 
   25:             "Due to a technical problem, the product details cannot be displayed.");
   26:     }
   27: }

All the code from the presenter is now in a try catch block. In the catch, we call the ViewExceptionHandler to handle the error. In this case, handling the error means: Log the error and show a ‘friendly’ error message.



Exceptionhandling in ListEventReceiver

Another ExceptionHandling strategy we’ve created is the ListExceptionhandler strategy.

If an unhandled exception occurs in a list, you should take the following actions:

  • Log the Exception
  • Set the ErrorMessage
  • Consider if you should cancel the action. We feel that de default action should be cancel, to avoid any potential harmful entries from entering your list.

So we’ve built a ListItemExceptionhandler that will do that for you.

Conclusion

As always, we hope you like the stuff we’re showing. If you have any feedback, comments or questions, feel free to ask me or the team (through the codeplex forums).