Chapter 8. Tools for troubleshooting and logging – SharePoint 2010 Web Parts in Action

Chapter 8. Tools for troubleshooting and logging

 

This chapter covers

  • Logging features in SharePoint
  • Error and exception handling
  • Debugging
  • The Developer Dashboard
  • Troubleshooting tools

 

In all projects, you’ll eventually have to perform some sort of troubleshooting. Depending on your support personnel’s troubleshooting skills and how the application is built, problems can be fixed before your users even notice them. Normally, a problem starts when a user receives an error and can’t resolve it. The user then reports the error and the problem escalates to your support team. If the error can’t be resolved by the support team, the troubleshooting will fall back on your developers or application management team. Without proper information from your support team, you’ll have a hard time reproducing the incident. Building Web Parts that correctly handle errors and unexpected situations allows you to more quickly resolve any issues—hopefully the support team will even be able to resolve it before it ends up on your desk.

In large-scale scenarios with possibly hundreds of thousands of users, it can be difficult to track down a single problem by searching the log files of the application. SharePoint has solved this issue by using a unique id for each request. When an error occurs, SharePoint presents that id to the user, who can then send it to the support team using, for example, a screen dump. By giving your Web Parts the ability to be monitored and using the SharePoint logging facilities, you can cut down the time needed to find the source of problems. Once you’ve figured out where and how the error happened, you have to reproduce this error to devise a resolution. You need different tools, depending on the type of error.

If the error is in the code, you might have to reproduce the error in your development environment and eventually debug the code. Visual Studio 2010 is your primary development environment, and you can use it to step through each line of code until you isolate the problem.

Sometimes you need to debug your application in an environment where you don’t have access to Visual Studio. For that purpose, SharePoint 2010 has a new feature called the Developer Dashboard, which shows detailed information about all exceptions and warnings on the current page. The dashboard can also be used to inspect the performance of each Web Part and its methods in a page—which is great when you need to optimize the application.

To avoid unnecessary support calls, it’s crucial to build robust code that handles exceptions and helps users avoid unhandled errors. Well written and robust are valid criteria for all kinds of development, but a single Web Part can make a page or whole site fail if it doesn’t handle exceptions correctly.

Visual Studio isn’t the only tool you’ll need when troubleshooting SharePoint and Web Parts. For specific scenarios, it may be important to have a JavaScript debugger if you don’t have access to Visual Studio. And you may need to inspect what has been transferred between the client and server by using web proxy tools.

8.1. Logging and error handling in SharePoint 2010

SharePoint 2010 contains numerous features to enable you to troubleshoot your applications while developing or running in production. All requests to SharePoint are given a unique id, which can be used to trace a specific error message to a request. This number is called the correlation id. Depending on how you’ve configured SharePoint errors, warnings and information messages are logged to the SharePoint-specific trace logs and databases, or to the Windows Event Log. All of these log entries contain a correlation id, which allows you to combine logs from different sources to get a bigger picture of a specific error or warning.

The correlation id is new in SharePoint 2010. This unique value is shown on the default error page. The default error page never shows the exact error that the end users saw, but users can send the correlation id to the support team for further investigation. Any custom logging to the log files will also contain this specific id.

The trace logs, also called Unified Logging Service (ULS)/ logs, are a primary source when you’re searching for exceptions and problems with your SharePoint installation. You can monitor these log files with external monitoring systems and search them by using simple text editing tools or PowerShell.

8.1.1. Introducing the correlation id

Errors can be shown in various ways in SharePoint. Unhandled errors and exceptions will eventually be displayed using the SharePoint error page (unless you’ve turned it off). This custom error page displays the following message: “An unexpected error has occurred.” Although this error message doesn’t help you with anything, SharePoint 2010 always displays a unique error id called the correlation id, as shown in figure 8.1. One of the reasons not to show the actual error message is that it can reveal too much of the actual code and call stack in the application and open it up for hacking attempts.

Figure 8.1. The default error page in SharePoint 2010 doesn’t show any information about the error but instead shows a correlation id that you can use when searching for the error in the logs.

The correlation id is guaranteed to be unique for that particular error at that given time. It won’t give any clues or help to an end user, but for an administrator this error message is important. An administrator can use the correlation id to look in the log files for the error message and source. Not only does SharePoint assign correlation ids to errors, but it also assigns every request and action a correlation id. This number is consistent over the whole farm and across service applications.

 

Tip

If you want, you can customize the error page to provide your end users with more information or instruct them to send the error message to the support team. The error page is located in {SharePoint Root}/TEMPLATE/LAYOUTS/and is called error.aspx.

 

If an unhandled error occurs on a Web Part or Wiki page, a link to the Web Parts Maintenance page is provided. Click this link to inspect the Web Parts on the page and remove the ones that are failing.

8.1.2. SharePoint trace logs

Almost everything in SharePoint can be logged. SharePoint logs information to the Unified Logging Service, which stores the information in the file system under {SharePoint Root}\LOGS. These logs are called the ULS logs, or trace logs. All events can be logged to the trace logs, and some information is also logged to the standard Windows Event Logs. You configure what and how much to log in the trace and event logs in Central Administration > Monitoring > Configure Diagnostics Logging, as shown in figure 8.2.

Figure 8.2. The logging levels for the trace and event logs is configured in Central Administration.

The trace logs always contain the correlation id, and this number is preserved over multiple servers—for example, when service applications are invoked on other servers. That way, you can easily locate any errors. The log files are plain-text files and can be opened with any text editing tool, but it can be hard to search and get an overview of the events using those tools. Several tools that will help you search and monitor the log files are available for download. One tool I recommend is the ULS Viewer by Microsoft, which can be downloaded at http://code.msdn.microsoft.com/ULSViewer.

8.1.3. Searching the trace logs

The SharePoint PowerShell snap-in also has a set of commands that allow you to work with the trace logs. For example, you’ll find the Get-SPLogEvent cmdlet useful when searching for errors using the correlation id. Assume that you have a Web Part that has failed in your production environment; your user reports the error to you but you only get the correlation id. You can either use one of the tools or this cmdlet to find out exactly what happened, if logging is enabled. To retrieve all logged information about a specific correlation id, use this PowerShell command:

Get-SPLogEvent |
Where{$_.Correlation -eq "a53ba71b-4231-4222-ac7e-4535dcf0c534"} |
Format-Table Category, Message -Autosize

The Get-SPLogEvent cmdlet returns records from all the trace log files on the current server. All records containing the specified correlation id are returned using the Where command. Finally, the category and message properties are formatted as an auto-sized table. The result of this command might look like figure 8.3, in which you see that there’s an exception thrown by a Web Part.

Figure 8.3. Using PowerShell to search for logged events related to a specific correlation id makes it easier to find the source of any problems.

If you need to use log files from multiple servers, use the Merge-SPLogFile cmdlet to merge all trace log files from all servers into a new local log file. The Get-SPLog-Event cmdlet can then be used on that new merged file to search for different records. Since the log files can grow to very large sizes I have found it very convenient to use the New-SPLogFile cmdlet. This cmdlet creates a new log file on demand. I use it in most of my scripts so that I can isolate the log events and have less information to search within.

In SharePoint 2010, some information is also logged to a specific log database, normally called WSS_Logging. If you have SharePoint 2010 Server, the trace logs are added to this database as well as to the log files on the disk. This allows you to query the database instead or even build a Web Part that takes the correlation id as input and outputs all the corresponding records.

8.1.4. Custom logging to trace logs

The ULS has an API so that you can write customized records to the logs. This API is available both in SharePoint 2010 Foundation as well as in the Server editions. Writing to the trace log can be valuable for many reasons, such as generic logging and logging of handled exceptions.

To add custom logging to a Web Part project, use the SPDiagnosticsService class, which exists in the Microsoft.SharePoint.Administration namespace in the Microsoft.SharePoint assembly. This class has two interesting methods you can use when logging information:

  • WriteTrace()—Writes to the SharePoint trace log
  • WriteEvent()—Writes to the Windows event log and possibly to the trace log

Both methods have nearly the same signature but write to different locations. Writing to the Windows event log may be desirable if there are some serious errors that must be escalated to systems monitoring the event logs. Normally the SharePoint trace logs are the best way to go. Listing 8.1 shows how to write to the trace log and write the current correlation id in the Web Part. This can be a good practice if you’d like your users to report the correlation id if any errors occur so that you can find the source of the error.

Listing 8.1. Using the correlation id in custom error messages

To get the current correlation id, the EventActivityIdControl method is imported from the advapi32.dll file. This Web Part throws an exception in the code, which is caught. To write to the trace log, the local diagnostics service is retrieved, and using the WriteTrace method , the exception is logged. The first parameter is a custom id of the log record. The second parameter describes the category of the record and includes a name and the default throttling levels for the trace and event logs. The severity level of the current record is also supplied, as well as the error message with its optional parameters. The correlation id is retrieved by invoking the imported EventActivityIdControl method . The user is informed about the correlation id by adding a Label control to the Web Part.

Notice that the SPDiagnosticsService class used to write to the trace logs isn’t available for use in sandboxed solutions. The imported method that acquires the correlation id isn’t either allowed when running code in sandboxed solutions.

 

Tip

Microsoft Systems Center Operations Manager is monitoring software that can be used to monitor SharePoint using the ULS Logs.

 

8.1.5. Error handling in sandboxed solutions

If an unhandled exception occurs in a sandboxed solution, the exception is caught and handled by SharePoint. SharePoint then presents a more developer-friendly error message than the default error page. If debugging is enabled, then the error details can be shown, as you can see in figure 8.4.

Figure 8.4. Sandboxed solutions that fail don’t show the default SharePoint error page. If debugging is enabled, the complete call stack is shown, which allows you to find the source of the exception. The stack traces are usually long for sandboxed solutions because several processes are involved.

All unhandled exceptions in sandboxed solutions are monitored and accounted for in the resource usage. This means that if the solution throws many exceptions, then the whole sandbox for the site collection eventually will be shut down, so handling the exceptions correctly is crucial for sandboxed solutions.

To log and monitor exceptions and other information, you need to create a logging mechanism of your own. You could create a full-trust proxy that uses the trace logging as described earlier. Another approach is to use the Business Connectivity Services (BCS) and log information to a custom database exposed as an external list. Note that if you start to log to a list or to a BCS source, you’ll start consuming sandbox resource points, but less points than exceptions are accounted for.

8.2. Debugging Web Parts with Visual Studio 2010

Logging is most often used when your solutions are deployed to look at the application’s behavioral history, even though the ULSViewer tool allows you to see the logging as it happens. To see your custom application in real time and step through the code to find the failing parts, debugging is extremely useful. Debugging is the most common way to find what’s wrong with your code. Using the excellent debugging facilities in Visual Studio 2010, you can easily set a breakpoint in your code and run your application. When the breakpoint is reached, the execution is interrupted and you can step forward or inspect the values of objects and even change them. To debug a Web Part or any other piece of code, attach Visual Studio to a process on the server so that it can catch the debugging events. SharePoint normally uses the ASP.NET worker process to run the code. But sandboxed solutions are executed in their own process, and Feature receivers run in the SharePoint timer job process, which means that you might have to attach the debugger to other processes than Visual Studio by default attaches to.

8.2.1. Attaching to processes

The SharePoint Developer Tools for Visual Studio 2010 allows for easy debugging of Web Parts and other SharePoint solutions. When you press F5 or select Debug > Start Debugging, Visual Studio automatically attaches to the correct processes.

The first thing Visual Studio does is verify that debugging is enabled on the web application; if it’s not, you’ll receive a prompt asking if you want to enable it, as shown in figure 8.5.

Figure 8.5. The first time a solution is debugged in a new web application using Visual Studio, you’re asked to enable the debugging.

Debugging is configured in the web.config file of the web application and when Visual Studio enables debugging, it changes three attributes in the file, as shown in table 8.1. These values can be changed manually as well. Remember to use this feature with caution in production environments because enabled debugging may slow down your application, and it will show detailed error messages to your users.

Table 8.1. The attributes used when changing to debug mode

Attribute

Description

debug<configuration><system.web><compilation _ debug="true|false"/> When set to true, debugging mode is enabled on the web application. The default value is false.
mode
<configuration><system.web><customErrors _
mode="On|Off|RemoteOnly"/>
Sets the type of error page to use. The default value is On in SharePoint, which shows the SharePoint error page. When set to Off, it shows the default ASP.NET error page. If the value is RemoteOnly, then only local access to the site shows the ASP.NET default error page.
Callstack
<configuration><SharePoint><SafeMode _
CallStack="true|false"/>
Indicates whether the call stack of the error should be shown. The default value is false. To show the detailed error messages, this must be set to true.

When customErrors is set to Off and the CallStack property is set to true in web.config, SharePoint will no longer show the friendly error message. It will instead show the ASP.NET error page, also known as the Yellow Screen of Death. This error page shows the exact exception and the call stack of the failing component, and you’ll find it useful when troubleshooting Web Parts or other components.

Another way to start debugging is to attach to the processes manually. Use this approach if you’d like to debug an already running session. The SharePoint web application processes run in the standard ASP.NET worker w3wp.exe processes. To attach to a process using Visual Studio, select Debug > Attach To Process. Be sure that the Show Processes From All Users and Show Processes In All Sessions options are checked. Then select the w3wp.exe process to attach to and click Attach. There might be several w3wp.exe processes, and you can safely attach to all of them. Or you can use the IIS management console to find the process id of the application pool and then select the correct process.

 

Tip

If you need to retrieve detailed information about errors, such as line numbers and filenames in the production environment, distribute your code using debug built files. You should never use debug builds in production unless necessary.

 

8.2.2. Debugging sandboxed solutions

Sandboxed solutions aren’t executed in the ASP.NET worker process w3wp.exe. Instead, they’re executed in the special SharePoint Sandbox Code Service. Visual Studio is aware of this, and if you press F5 to run and debug your sandboxed solution, Visual Studio attaches to the correct process. The process that’s used is named SPUCWorkerProcess.exe, and you have to attach to this process if you manually attach Visual Studio to debug a sandboxed solution.

If you’re debugging a sandboxed solution that uses a user code proxy, then this code is executed in the User Code Proxy service. This is a special service, named SPUCWorkerProcessProxy.exe, that runs under full trust. You need to manually attach to this process when debugging user code proxy code.

8.2.3. Debugging feature receivers

Features are automatically activated by default in Visual Studio. You can change this behavior by editing the deployment configuration, discussed in chapter 3. Depending on how the activation/deactivation is done, you have to attach to different processes. If you have to debug the FeatureActivated or FeatureDeactivating methods from the web interface, attach to the ASP.NET worker process, w3wp.exe. And if you’re enabling it using PowerShell, then you have to attach to the PowerShell.exe process.

Solution installation and uninstallation are accomplished using the SharePoint timer job. The FeatureInstalled, FeatureUninstalling, and FeatureUpgrading methods are executed by owstimer.exe. Notice that your breakpoints may not be hit immediately. You might have to wait a couple of seconds until the timer job starts and invokes the Feature receiver.

8.3. The Developer Dashboard

Visual Studio can help with troubleshooting, but normally debugging only works in the development environment. Once your application ends up in a nondevelopment environment, you can’t set a breakpoint in your code to inspect the state of the application. You must have tools that you can use in production environments to show you how your application performs and behaves.

SharePoint 2010 contains a new monitoring feature called the Developer Dashboard. It’s a special dashboard that can be enabled on pages; it shows all the current activity on a page, including timing, logs, warnings, and errors. By using the Developer Dashboard and by defining scopes in your code that can be monitored, you can identify which piece of your code is failing. In the following section, you’ll learn how to work with the Developer Dashboard and how to incorporate logging into the dashboard by making your Web Parts aware of the monitoring facilities.

8.3.1. Enabling the Developer Dashboard

The Developer Dashboard isn’t enabled by default in SharePoint 2010; you have to actively enable it. There’s no functionality in the user interface for this feature out of the box, and you must use scripts or create custom code to enable it. The Developer Dashboard mode is set for the whole farm.

The easiest way to enable the Developer Dashboard is to use the STSADM command and use the setproperty operation. The operation is used to assign a value to the developer-dashboard property. This property can have one of three possible values and represents the mode of the Developer Dashboard:

  • Off—The dashboard is never shown or available.
  • On—The dashboard is always shown and accessible.
  • OnDemand—The user can turn on the dashboard when it’s needed.

The STSADM command has to be run from an elevated (Run as Administrator) command prompt or PowerShell window. You’ll find the STSADM.exe file in the {SharePoint Root}\bin folder. The three different modes can be set like this:

stsadm.exe -o setproperty -pn developer-dashboard -pv on
stsadm.exe -o setproperty -pn developer-dashboard -pv off
stsadm.exe -o setproperty -pn developer-dashboard -pv ondemand

The first command turns on the Developer Dashboard and the second turns it off. The third command, which I recommend that you run on all your development farms, sets it to On Demand mode. When On Demand mode is configured, an icon will appear in the upper-right corner that users can click to open and close the Developer Dashboard, as shown in figure 8.6.

Figure 8.6. When the Developer Dashboard is set to On Demand mode, users can turn the dashboard on and off by clicking the icon in the upper-right corner.

The Developer Dashboard can be enabled through code as well. When configuring the dashboard through code, you have more options for the dashboard. The configuration is done using the SPDeveloperDashboardSettings class. The following code snippet shows how to set the Developer Dashboard in OnDemand mode and only make it available for users with full permissions on the current website:

SPDeveloperDashboardSettings settings =
    SPWebService.ContentService.DeveloperDashboardSettings;
settings.DisplayLevel = SPDeveloperDashboardLevel.OnDemand;
settings.RequiredPermissions = SPBasePermissions.FullMask;
settings.Update();

The current settings object for the Developer Dashboard is acquired from the web service of the content application. The settings are then configured, the mode is set to OnDemand, and the required permissions are set to full permissions. Finally, the settings object is updated to save the changes.

 

Tip

If you’d like to have a web interface for configuring all different parameters in the Developer Dashboard, you can download a solution package that adds configuration options for the Developer Dashboard in Central Administration. Download it from my blog at http://www.wictorwilen.se/Post/SharePoint-2010-Developer-Dashboard-configuration-feature.aspx.

 

8.3.2. Using the Developer Dashboard

The Developer Dashboard is a quick and useful tool to use when troubleshooting, working, and tuning your Web Parts. When the dashboard is set to be available at all times, it appears at the bottom of each page in SharePoint. And when you set it to On Demand, you can display it by clicking the Developer Dashboard icon in the upper-right corner. The Dashboard contains information about the current page and request. Figure 8.7 shows an example of how it might look.

Figure 8.7. The Developer Dashboard in SharePoint 2010 shows the details of a specific request.

The Developer Dashboard has a border in green, yellow, or red. A red border means that some of the monitored metrics have excessive values or that one or more critical events are logged. A yellow border indicates that the request took more than one second, and green indicates that the page was most likely successful. On the left side are all monitored events and method calls, including their execution time. This call tree is useful when you’re looking for performance bottlenecks. The right column contains more information about the current request, including the total execution time, correlation id, and all database queries. If you click on one of the database queries, you’ll get even more information about them.

8.3.3. Using monitored scopes

SharePoint 2010 introduces a new way to monitor custom applications. Using monitored scopes you can easily hook into the Developer Dashboard call tree and display your own operations. The standard call in the Developer Dashboard contains only the default events called by SharePoint, but a custom application most often contains more methods and classes that should be monitored.

Custom monitored scopes are created by instantiating a new object of the type SPMonitoredScope. This starts a new scope when created and ends the scope when you dispose of it. Figure 8.8 shows how custom scopes are added to a Web Part. A custom scope is added to the CreateChildControls method, and it calls two other monitored methods. By looking at the execution time, you can easily see which method performs slowly.

Figure 8.8. The Developer Dashboard shows all the monitored scopes and their execution time. This allows you to locate the parts of the Web Part that can be causing a bottleneck.

Listing 8.2 shows the code for realizing the custom scopes shown in figure 8.7. Notice that the usage pattern is used to properly dispose of the SPMonitoredScope objects when the scope is over. Monitored scopes aren’t supported in sandboxed solutions.

Listing 8.2. A Web Part using monitored scopes

In the CreateChildControls method, a scope is created with the name of the method . Inside this scope the two methods are called . The first method creates another scope and then pauses the thread for 1.2 seconds. The second method also creates its own scope . As seen in figure 8.8, you can immediately identify where the code performs badly and where the call is coming from.

8.3.4. Logging using scoped performance monitors

Logging can be improved using custom scoped performance monitors. A custom monitor is a class deriving from the ISPScopedPerformanceMonitor interface. Monitors can be used to monitor and log actions in your custom code. For instance, you could use a monitor to log the number of calls made to a specific web service or a specific code that uses other expensive resources in the trace log. Each monitor can also have a threshold that’s monitored by SharePoint. Classes implemented from this interface can be passed as arguments to a monitored scope.

To illustrate the use of a custom scoped performance monitor, let’s create a simple monitor that increments a static value each time the monitor is used in a monitored scope. When the value exceeds a threshold, it should be logged to the trace logs. Listing 8.3 shows how to implement the custom monitor.

Listing 8.3. A custom scoped performance monitor

The custom monitor class, which is derived from the ISPScopedPerformanceMonitor interface, instantiates a static counter variable . The constructor, which is called each time the monitor is used, increments the value of the counter in a thread-safe way. The Description property and the RenderValueForWeb method can’t be used by custom applications and are only used by SharePoint managed monitors. The Name property is used when logging to the trace logs. To get the value of the monitor, the class returns the current value of the counter using the Value property . SharePoint uses the ValueIsExcessive method to ask the monitor if it has passed the threshold. In this sample, it should start logging when the monitor has been used more than five times.

This custom monitor is passed as an argument to a monitored scope, as shown in the following code snippet. The second required argument is a value for the maximum execution time. This value is converted into a specific scoped performance monitor that monitors the execution time of the scope. The default value is 100 milliseconds.

using (SPMonitoredScope scope =
    new SPMonitoredScope("Custom scope", 100, new CustomMonitor())) {
    // ...
}

If you run this code in a Web Part, the logging will start as soon as the monitor has been used more than five times. The logged information will look like this in the ULS logs:

Leaving Monitored Scope (Iterations). Execution Time=0.481799409360119
____CallCounter=7
____Execution Time=0.481799409360119

Each line starting with four underscore characters represents the value of one monitor. In this example, it’s the custom monitor and the automatically created execution time monitor. If the SharePoint Foundation > Monitoring category is set to Verbose, the logging will occur even if the value isn’t excessive. When writing to the log, all values from all active monitors are written regardless of which monitor had excessive values.

The Developer Dashboard configuration object also contains a property called AutoLaunch. If you’ve set the dashboard to On Demand mode and the Auto Launch property to true, then the Developer Dashboard will automatically appear if any critical events defined in SharePoint are logged.

8.3.5. Custom logging to the Developer Dashboard

When you’re rendering a Web Part, SharePoint creates a top-level scope. One of the monitors that SharePoint adds to this scope is the SPCriticalCounter monitor. This monitor can be used to insert information into the Assert and Critical Events section in the Developer Dashboard. Figure 8.9 shows a custom entry written to the dashboard. By clicking on the logged entry in the dashboard, you display more information about the event. The information contains an event message and the current call stack.

Figure 8.9. Asserts and critical events are shown in the Developer Dashboard; you can click on them for more details.

To add custom entries to the Asserts and Critical Events section, use a static method of the SPCriticalCounter class. SharePoint will automatically add this monitor, together with a set of other monitors, when it receives a request. To add a custom entry to the Developer Dashboard, use the static AddDataToScope method of the SPCriticalCounter like this:

using (SPMonitoredScope scope = new SPMonitoredScope("Critical")) {
    SPCriticalTraceCounter.AddDataToScope(
        2010,
        "Critical Error",
        15,
        "An error occurred");
}

Using the static AddDataToScope method, a new entry is created. The first parameter is a custom tag id to identify the entry. The message shown in the Developer Dashboard is the category parameter of the entry, and the trace level is specified using an integer. The trace level corresponds to the internal Microsoft.SharePoint.Diagnostics.ULSTraceLevel enumeration. The value 15 corresponds to the Monitorable value. The last parameter contains the actual message. As of this writing, this enumeration isn’t documented on MSDN, so you have to use the .NET Reflector tool to discern the actual values.

8.4. Custom error handling

Knowing how and when to catch exceptions is important. Always check your parameters for null before using them. Eventually exceptions will get thrown and just catching an exception and ignoring it won’t make it easier to troubleshoot the application. That will only leave you and your users unaware of any problems. Not all exceptions should be caught—only catch exceptions that can be handled. Exceptions that can’t be handled should instead fall through to SharePoint, which will eventually log the exception. There’s a distinction between system exceptions and business logic errors. For instance, an Access Denied exception shouldn’t always be handled; it can fall through to SharePoint, unless it’s important for business logic to handle that exception. This isn’t specific to SharePoint; it’s good practice in all .NET development. In SharePoint with Web Parts it’s important to do this correctly. A page in SharePoint can contain several Web Parts, and one single failing Web Part can make the whole page useless.

One common method is to use a generic try-catch block that will catch any exception just to avoid displaying error messages to the users. Although using a try-catch block could keep the solution from displaying unwanted errors or sensitive information, this method of catching all exceptions makes users unaware of what went wrong and they’ll have problems resolving or reporting the error. Being unaware of what failed in business-critical applications can be fatal. Consider an application making a financial transfer that fails and the user doesn’t notice what made it fail:

void button_Click(object sender, EventArgs e) {
    try {
        float amount = float.Parse(textBox.Text);
        TransferMoney(amount);
    }
    catch (Exception) {
        label.Text = "Transfer failed";
        return;
    }
    label.Text = "Succeeded";
}

This snippet is a response to a button click; it takes the value of a text box and parses it into a float value before it uses a method to transfer the amount of money. The generic catch statement will catch all kinds of exceptions and inform the user that the transfer failed—but not why. Even worse would be just catching the exception and not doing anything.

In this simple example, users won’t know whether they entered an invalid value or the money transfer failed. A better approach is in this case to catch only exceptions of the type FormatException. All other exceptions will be let through to the SharePoint exception handling.

void button_Click2(object sender, EventArgs e) {
    try {
        float amount = float.Parse(textBox.Text);
        TransferMoney(amount);
    }
    catch (FormatException) {
        label.Text = "Invalid amount format";
        return;
    }
    label.Text = "Succeeded";
}

The procedure is the same as in the previous snippet; the text box value is converted to a float value and the float value is passed to the money transfer method. The catch statement only catches exceptions of the type FormatException and tells users that the value they entered is in the wrong format. Any other exceptions are unhandled and fall through to the SharePoint error page. This approach improves the overall experience and ensures that the severe exceptions from the submethod are logged.

SharePoint uses the default error page when unhandled exceptions fall through (see section 8.1.1). If you catch and handle exceptions in your code, you need to follow these best practices:

  • Provide user-friendly messages.
  • Avoid exposing sensitive information and data in error messages.
  • Clean up resources in a correct way.
  • Leave application in a consistent way.
  • Log any errors that are unexpected and can’t be handled by the user.
  • Don’t use exceptions to control the business logic.
  • Rethrow exceptions that aren’t handled.

If you can’t follow these principles, leave the error handling to SharePoint. Take a look at listing 8.1, which catches an exception, logs the exception details, and displays an error message to the user.

Exception handling in sandboxed solutions is of particular interest, because any unhandled exceptions will count in the solution resource point usage. If a solution uses too many resources, the whole Solution Gallery for the site collection will be shut down. Because the SharePoint logging API isn’t available in sandboxed solutions, you need to set a logging strategy for this. Consider creating a full-trust proxy for logging or log to a SharePoint list.

8.5. Other debugging tools

Everyone has their own set of tools and methodologies to troubleshoot web-based applications, and SharePoint is almost just like any other web application. You can most likely use the tools you’re used to, but I’d like to highlight a few.

When troubleshooting the server-side code, Visual Studio is your primary tool along with the logging techniques we discussed earlier. ASP.NET developers have access to a built-in tracing tool in ASP.NET, and this tool can be used in SharePoint.

Even though Visual Studio 2010 is great for debugging JavaScript, there are alternatives such as the built-in tools in Internet Explorer or the Firebug extensions to Firefox. These tools, in combination with web proxy tools like Fiddler, can prove valuable when you’re troubleshooting JavaScripts or when you need to inspect what’s sent to SharePoint and what’s sent back.

8.5.1. ASP.NET tracing

ASP.NET includes a method that lets you view diagnostic information about a page and the request. If you’re an ASP.NET developer, you’re familiar with it. In previous versions of SharePoint in which the Developer Dashboard didn’t exist, this method was a good resource for troubleshooting. The tracing is written immediately following the page’s output and contains tables with diagnostics information such as the following:

  • Trace information and exact timings between the events
  • Control tree containing all ids for all controls
  • Information about the session and cookies
  • Information about all header, form, and query string parameters

Some of the information overlaps with the Developer Dashboard, but if you need to get more information about, for instance, the form parameters passed to the page, you must enable the ASP.NET tracing.

The Developer Dashboard settings object (SPDeveloperDashboardSettings) contains a property called TraceEnabled. When this property is set to true, a link is inserted at the bottom of the Developer Dashboard. You click this link to turn on the ASP.NET tracing information, as shown in figure 8.10. Click the link again to turn off the ASP.NET tracing.

Figure 8.10. When ASP.NET tracing is enabled in the Developer Dashboard, the ASP.NET trace is shown at the bottom of the page.

8.5.2. Internet Explorer Developer Tools or Firebug

Tools for troubleshooting the client side of SharePoint are also important when developing and troubleshooting Web Parts. In chapter 4 I mentioned Internet Explorer 8/9 Developer Tools and the Firefox browser Firebug extension. Both of these tools have debugging capabilities that can help you figure out problems with JavaScript functions. Even though Visual Studio 2010 automatically attaches the debugger to Internet Explorer, when debugging the project you can only do it on a development machine. The client tools can be used on production servers directly without any installations. You can use these tools to set breakpoints in JavaScript and step through the code and watch variables and objects.

8.5.3. Fiddler web proxy

Another helpful tool that should be in your developer toolbox is Fiddler. Fiddler is a web debugging proxy that logs all HTTP traffic going from your development machine to any web server, local or remote. Use Fiddler to find problems or optimize your applications when they’re running in production. It doesn’t affect SharePoint at all; it just captures all traffic from the web browser to SharePoint. You can inspect all requests and responses to see exactly what data is transferred between the client and SharePoint. You can download Fiddler (for free) at http://www.fiddler2.com/fiddler2/. Figure 8.11 shows how Fiddler looks when it catches all communication from the client to the server.

Figure 8.11. Fiddler inspects all outgoing and incoming web traffic.

You can use Fiddler to manually send specific requests to the server. It also monitors the exact time and amount of data transferred. This information can be used to optimize your applications along with the timeline view, which shows the order and time it takes for all items requested by a page to get loaded.

8.6. Summary

This chapter explored both generic .NET and SharePoint-specific error handling. SharePoint is built on Microsoft .NET and ASP.NET, and you can use the same techniques for handling errors and troubleshooting them. SharePoint contains a set of out-of-the-box tools like the logging features and the Developer Dashboard tool that will prove valuable when you’re troubleshooting Web Parts.

Many tools are available, including Visual Studio. We discussed a few of my favorites that I use both when developing Web Parts and when the Web Parts are running in a production environment. Hopefully this chapter will help you avoid some troubleshooting, but eventually we all end up with a Web Part that doesn’t act as intended.