This series of articles is intended to help you getting ramped up with SharePoint programming. It’s about writing, troubleshooting and debugging SharePoint code. First you need to have prerequisite skills in .NET Development and in particular ASP.NET Development, you should also have basic understanding of SharePoint and how to use it from the User Interface , you must be able to create and deploy features and you should have some experience in working with content types and site columns.
Ready? Let’s get started!
The terms “Bug” and “Debugging” are facts of a programmer’s life. Debugging in general is a lengthy and tiresome task. In my mind, for you to be a good SharePoint developer, you must know how to troubleshoot your applications. The trick is SharePoint debugging can be quite complex for those who are new to the platform, that’s why I decided to kick off my series of articles with how to simplify Debugging SharePoint code before we dive deep into the world of SharePoint programming. At the end of the article we’ll create the “SharePoint troubleshooting toolbox” that we’ll frequently use in our series “Getting Started to SharePoint Programming“.
Simplifying SharePoint Debugging By Creating The Troubleshooting Toolbox
Debugging in WSS or MOSS is similar to debugging an ASP.NET application but unfortunately debugging custom code in SharePoint isn’t as easy as just pressing F5 from inside Visual studio. While SharePoint provides an excellent platform for developing Web applications, debugging them can be a bit of a pain. In this article I will give you some debugging tips that could make your life easier and will help you deal with the silly “An unexpected error has occurred” screens. Also I will shed the light on some tools provided by the SharePoint community that facilitate the troubleshooting of SharePoint applications and error isolation and accordingly increasing your productivity.
Five main resources are available for you when you experience a problem:
1. Detailed Error Messages
2. Attaching the Visual Studio Debugger to W3WP.EXE
3. SharePoint Trace Logs
4. Windows Event Logs
5. Debug And Trace
1. Detailed Error Messages Vs. The Annoying Page!
Usually, an error message will be your first indication that something went wrong. Unfortunately, SharePoint uses a user friendly (Yellow & Blue) error page to show that a problem occurred. Yeah, they call it the user friendly page, but we, as developers, call it the Annoying Page. The first time I wrote SharePoint code, I received a screen like the one shown in the figure below:
This error page points out that an assembly has thrown an unhandled System.Exception. Sometimes, the user-friendly error page will specify the nature of the error if the code that threw the exception used something more specific than System.Exception or if it included a message in the Exception class constructor.
We need to get a more detailed Error Message than the annoying “Unexpected error has occurred “. This can be achieved by doing three modifications to the Web.Config file from the virtual directory containing your SharePoint application. These modifications are listed in the next table.
Off or Remote Only
No Custom Errors shows the full error to every client, every time. This is typically used Development environment, since there are no clients using it.
Remote-Only Custom Errors allow you to display custom errors only to remote clients. This means that if you are browsing your SharePoint site locally, you will get the fully detailed error messages. However, anybody else will receive the standard SharePoint page.
I recommend using the Debug Config feature to automate this process. This is just a feature that when you activate on a web application, it automatically tweaks the Web.Config of the specified web application across the farm.
2. Attaching the Visual Studio Debugger to W3WP.EXE
Now you have the standard ASP.NET error page with a stack trace , OK this is very helpful but you don’t want to guess what the problem might be and randomly change your code to fix it.
First thing you need to do to avoid the old fashioned trial and error technique is to enable debugging. This could be achieved by setting the compilation element debug attribute to true in Web.Config from the virtual directory containing your SharePoint application, otherwise, breakpoints inside Visual Studio will be shown but will never be used.
Once you’ve done that, there is one more thing you need to do in order to be able to debug your SharePoint code in Visual studio which is attaching a debugger to W3WP.EXE, Attaching a debugger in Visual Studio will allow you to step through the code and find exactly where the error occurs.
It’s really handy but there are three questions that I always receive from my colleagues when they get started to SharePoint programming, so I decided to share the answers with you.
The first one is: Sometimes, I set breakpoints and attach to the process but Visual Studio skips loading the symbols if I’m debugging a deployed assembly to the GAC and I fail to debug the code
Easy, Open Tools -> Options -> Debugging.
You’ll find an option labeled Enable Just My Code (Managed Only) as shown in the figure which is checked by default. Uncheck this option to be able to debug the assemblies located in the GAC. There is a common myth among .NET developers in general and especially SharePoint ones, that in order to debug assemblies that have been deployed to the GAC, you need to copy the debug symbols (PDB File) to the GAC as well. This was true in the early days of .NET but this is no longer true.
The second one is: When I try to attach the debugger to the W3WP.exe process to debug, I always see multiple instances of it. Which one should I attach to?
Ok, this is easy too. Just follow the following steps.
- Open the command prompt window, run IISAPP to get a list of the current instances of W3WP.exe.
- Note the PID of the instance that corresponds to your web application.
- Now return to VS, select Debug -> Attach to process and attach to the W3wp.exe instance with an ID equivalent to the PID you got in step 2 -> click Attach.
- Now you can trace through the code and find the error causes easily.
But the question still remains, why sometimes are they more than one w3wp.exe instance? This is because the SharePoint Administration Site Collection and the SSP Administration site always have their own Application pools for error isolation purposes.
And the third question is : Is it possible to debug Inline code blocks ?
Actually, I hate Inline Code Blocks and it’s really a good practice to avoid it due to the performance issues when the JIT compiler compiles them but YES, you can do that.
So now you knew the process of debugging? Very boring and repetitive huh? Hmm, Can’t that be automated?
Fortunately Jonathan Dibble, a brilliant developer, created a very handy “Debugger Feature” that can be installed and activated on a SharePoint site to automate this process. Once activated, the Debugger Feature adds an “Attach Debugger” menu item to the Site Actions menu. Extremely helpful and faster than doing that from visual studio.
3. Unified Logging Services ( SharePoint Trace Logs )
Sometimes you receive error screens while activating a feature or creating a Site Collection or during deploying packages. For instance, a couple of months ago I got an annoying error “File not found” when creating a site collection from a custom template!
SharePoint trace logs are at your disposal when you need to troubleshoot errors occurring before and after custom code; they are very useful in the deployment and provisioning operations as they are the main sources of information about everything happening inside SharePoint.
Most of SharePoint components use the Unified Logging Services (ULS), those logs are normal text files and you can find them in the 12 hive at 12\Logs. You can tweak the ULS settings via the Diagnostic logging link under Logging and Reporting in the operations section of SharePoint central administration to control the verbosity of events captured in the Log files, you can modify the settings per category or for all the categories as shown in the figure; thus modifying the number of events captured. The list entries are sorted in order from most-critical to least-critical. I always just set all of the categories to verbose because it’s sometimes difficult to specify the categories needed to be changed when a problem occurs.
If you want to tweak the verbosity setting per category, make sure to leave the default value of the General category for trace logging as it is (Verbose) because entries about the provisioning and deployment processes are logged under the General category. Also be aware that updating all categories will make you lose the changes you made to individual ones.
When you choose to increase the number of events captured by the ULS, you will find the log files very cluttered and hard to use, and SharePoint provides no built-in viewer. To fill the gap and facilitate troubleshooting, free third-party tools exist like LogViewer, SPTraceView and WSS/MOSS Log File Reader .Some utilities including SPTraceView will aggregate log data from more than one server in the farm.
Next figure shows LogViewer in action.
I’d also like to point out that you can write code that incorporates logging to MOSS logs. Writing to the same trace log alleviates the need for developers to log their development information in other places such as the Windows Event Log, which is more commonly used by system administrators.
The only limitation to using the code snippet above is that you cannot set the log event level (e.g. low, medium, and critical) as it’ll always display the error level in the trace logs as High. The logger is located in 12\ISAPI \Microsoft.Office.Server.dll and therefore it’s only available with the MOSS install, not WSS 3.0.
What if you need to write into SharePoint trace logs while having full control on the error level? This is a pretty easy thing to do, because MSDN has a wonderful sample of code that you can reuse. I always use this code in my features.
Simply add the class to your project and then you can write to the logs using something like the following code.
TraceProvider.WriteTrace(TraceProvider.TagFromString(”XXXX (must be 4 letter tag)”), TraceProvider.StringToSeverity(”Exception or Information”), Guid.NewGuid(), “Method Name”, “Assembly Name”, “Project Name”, “Message”);
4. Windows Event Logs
You should include Windows Event Logs as part of your normal troubleshooting because it sometimes contains useful entries that SharePoint is unable to log via ULS. You can increase and decrease logging by severity level in the same way you do for ULS.
It’s possible to log errors to the system event log from your custom code but you need to promote the privileges as shown.
5. Debug And Trace
After you take your SharePoint site live, you are not the only one who is using it anymore (hopefully), so you need effective plans to track down errors.
System.Diagnostics.Debug and Trace statements are very useful in this case. Used in conjunction with DebugView you can determine what has gone wrong! Debug Calls are removed from the release builds, so you should use them in your development environment but Trace Calls remain in release code and so will add an overhead to the code execution yet they are very helpful when you cannot attach a debugger (for instance on the staging or the production environments) . Since manually adding trace calls might be time consuming, I would strongly recommend using a tool such as ReSharper to drop in these statements quickly rather than relying on typing or copy/paste. The next figure shows the trace output using DebugView.
SharePoint Troubleshooting Toolbox!
Well, let’s create our debugging toolbox, the following utilities should be included in our SharePoint debugging toolbox; we’ll certainly need them in our long journey with SharePoint development.
This was the first article in a series that will help you getting started with SharePoint programming and I decided to introduce you to some of the troubleshooting utilities and tools that can really make your life easier before getting our hands dirty with SharePoint code since troubleshooting can really be a nightmare for those who are new to the platform.