Digging Deep – A Guide to Debugging SharePoint Workflows

Description: An error has occured in your workflow.

When you first start building SharePoint workflows, you’ll sometimes get a nasty, empty feeling in the base of your stomach. It that feeling of venturing into the unknown and it’s usually accompanied by that dreaded Error Occured message. You were expecting a confidence-inducing In Progress message instead. Where to now? With all the quirks of SharePoint how do you get your workflow moving again?

This is no different than when a car breaks down. You… call a mechanic and hail a cab. Job done! Thanks for visiting my blog.

So, what happens when you’re out in the middle of the desert, in a foreign country, and you can’t afford a mechanic to save yourself? Well, it’s time to pop the hood and have a look at the engine, and that’s exactly what we’re going to do in this guide. Lucky for us, SharePoint’s quite a bit more expressive about what caused your workflow to stall. The trick, for developers, is in learning how to listen.

I’m going to write a couple of paragraphs on the following topics:

  1. Debugging local workflows: This is the quickest and easiest method of debugging. Visual Studio is running on the same computer as SharePoint. This case is most suited to debugging during development.
  2. Debugging remote workflows: So you debugged your code locally and the workflow’s been deployed into production. A month later it fails and you can’t replicate the problem on your development box. It’s time for some remote debugging. In this case Visual Studio is running on a different computer to SharePoint.
  3. Using the free ULS Log Viewer: This free SharePoint solution is my favourite development tool, bar none. I’d be lost without it. It provides a nice, simple view at the SharePoint log files and allows you to easily filter the results. Save yourself hours of ploughing through log files and use this tool.

Debugging Local Workflows

I’m going to be using the simplest of workflows to perform the debugging. It’s just a few lines of code to update a list item. To setup your project like mine:

  1. In Visual Studio (2k5 or 2k8), create a new SharePoint Sequential Workflow project and bind it to a standard document library on your site. Allow the wokflow to be initiated manually.
  2. Open the code for the onWorkflowActivated1 activity.
  3. Enter the following code. I’m not going to explain the code as I expect you understand the basics of SharePoint development.

private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
            SPListItem _item = workflowProperties.Item;
            _item["EmailAddress"] = sharepointgear@wordpress.com;
            using (SPSite _site = workflowProperties.Site)
            {
                _site.AllowUnsafeUpdates = true;
                using (SPWeb _web = workflowProperties.Web)
                {
                    _web.AllowUnsafeUpdates = true;
                    _item.Update();
                    _web.AllowUnsafeUpdates = false;
                }
                _site.AllowUnsafeUpdates = false;
            }
        }

  1. From the Build menu, select Deploy. This will deploy your workflow as a feature, register the DLL in the GAC and associate the workflow to your list.
  2. Add a new document to the library. Then, hover over the document in the list and from the drop-down (callled an ECB: Edit Control Block) select Workflows. On the next screen run your workflow. I called my workflow Debugging and here’s the error message:
    debuggin_listview
  3. Ok, so this is a very simple workflow and you can probably deduce that it failed when trying to update a field named “EmailAddress” which doesn’t exist.
  4. To debug the workflow we need to tell Visual Studio which IIS process is running our web site. IIS starts (forks) a separate process for each application pool running  your server. To identify the correct one, use a the iisapp.exe command line tool.
  5. Open Command Prompt and type iisap. You’ll see a result similar to this:
    debugging_iisapp
  6. You can see that I have four application pools running at once (waste of resources, I know). You named the application pools when you first created your SharePoint application. I name mine after the port number they run on, for easy reference. The site I’m using for this guide is running under the application pool: SharePoint – 7, with the PID (process ID): 3436. We use the PID to identify our application pool in Visual Studio.
  7. Back in Visual Studio, select Attach to Process from the Debug menu. You’ll be presented with a list of processes. Select the process with the same PID as your w3wp process. If you don’t see the process listed, ensure you enable the two checkboxes near the bottom of the dialog box:
    debugging_attachtoprocess
  8. Once you click the Attach button, you’ll be presented with a security warning. Click attach again and you’re connected to your workflow. Visual Studio is now monitoring the process, waiting for your code to be activated. So, let’s activate your code.
  9. At this stage, you could add a breakpoint in your code. This is especially useful if you want to inspect the logic in your code, or if you want to inspect a certain variable. Visual Studio will automatically break execution when it encounters and error, so we won’t use a breakpoint at this stage.
  10. Upload another document into the document library and activate the workflow. Visual Studio will monitor the workflow and break execution once it encounters an error:
    debugging_vsbreaks
  11. The error shows that _item[“EmailAddress”] is not a valid index. This helps identify that there’s a problem with the column name.

Once you break execution you can use all the traditional tools to troubleshoot the error. You can use immediates to evaluate variables and query objects, you can use autos, add watches, etc. One limitation is that you can’t directly edit the code during debugging.

Debugging Remote Workflows

Debugging remote workflows involves attaching to a process in much the same way as I’ve described above. So I won’t describe those steps again. Instead, I’ll discuss the differences and extra steps required to debug remotely. I will call the computer running Visual Studio the local server and the computer running SharePoint (and the remote debugger) the remote server. The process might initially look a bit heavy, but it’s quite painless after a bit of practise.

Installing the Visual Studio Remote Debugger

You’ll need to install the Visual Studio Remote Debugger that matches your specific version of Visual Studio. The debugger is installed on the remote server. If you’re running VS2008 SP1, download the remote debugger here: http://www.microsoft.com/downloads/details.aspx?FamilyID=440ec902-3260-4cdc-b11a-6a9070a2aaab&displaylang=en. If you’re using an older version of Visual Studio, you can find the remote debugger on your Visual Studio installation media. I’m writing this article from memory, but I’m pretty sure the installer gives you the option of running the debugger as a service (always on). I’ve never installed it like that, but it shouldn’t matter whether you install it as a service, or as a regular application.

Setting permissions for Remote Debugging

The user account that’s going to be doing the remote debugging (i.e. the user running Visual Studio) must have the appropriate permissions on the remote server. There’s two ways to ensure the account has the necessary permissions:

  1. Make the account a Local Administrator on the remote server. This is the less-preferred method and may not be allowed in many enterprises.
  2. Add the account to the Debugger Users group on the remote server. Much more appropriate, but I’ve had varying success in the past (probably due to the environment I was working in).

Copy the DLL and Debug Symbols to the Remote Server

This is the biggest trick with remote debugging. You need to copy the project’s debug symbols (pdb file) to the remote server’s GAC. The problem is that you can’t copy PDB files directly to the GAC via the Windows GUI. You need to use the Command Prompt instead. Follow this process to deploy your project’s DLL and PDB files to the remote server’s GAC.

  1. Copy the project’s DLL and PDB files (from the project’s Debug folder) to a temporary folder on the remote server.
  2. Jump onto the remote server’s console, or use a Terminal Services connection (if your IT policy won’t allow this, you’re going to need to use a comination of gacutil and a remote command prompt tool).
  3. Open the temp folder with the DLL file in one Windows Explorer window and C:\Windows\Assembly (the GAC) in a second Windows Explorer window. Drag the DLL file from the temp folder into the GAC. This will install the DLL into th GAC.
  4. Open a command prompt window and change directories to C:\Windows\Assembly.
  5. Do a directory listing (DIR) and you should see a directory named after the DLL you just copied. Change directories to your DLL’s folder (CD <directory name>).
  6. Do another directory listing and you should see a subdirectory named after your DLL’s version number; change to this directory (tip: type CD <space> then press TAB).
  7. Copy the PDB file from the temporary folder to this directory (XCOPY <source directory\filename> <destination directory>).
  8. Do an IISRESET (or reset the application pool with iisapp, it’s quicker). Remember that you’ll need to reset the application pool (or IISRESET) every time you update the DLL and PDB.

Starting the Remote Debugger

  1. After you install the remote debugger on your remote server, go ahead and start it up.
  2. You’ll be presented with the Remote Debugger Monitor: a really boring, empty screen. From the Tools menu, select Options. Here’s a picture of the Options screen:
    debugging_remotedebugger
  3. The Server Name field needs to be entered into Visual Studio, so copy it to the clipboard.

Attaching to the Remote Debugger

  1. In Visual Studio select Attach to Process from the Debug menu.
  2. In the Qualifier drop-down, paste the text you copied from the remote debugger’s Server Name field and press Enter.
  3. Visual Studio will now attempt to the remote debugger (and probably throw up a couple of security warning).
  4. You’ll know if the connection was successful by having a look at the Remote Debugger Monitor. You should now see a notice advising that you’re connected.

That’s it. You can now start your workflow from the local machine and Visual Studio will catch any exceptions and respect your breakpoints.

The ULS Log Viewer

The ULS Log Viewer is a SharePoint feature that’s made freely available on CodePlex as part of their SharePoint 2007 Features pack. It has to be the most useful community add-on that I’ve used and I install it on all my development environments.

Links:

Head over to the download page and grab a copy of  the Log Viewer feature. It downloads as a WSP (SharePoint solution). Once installed, it creates a link at the bottom of the Operations page of Central Administration. This log viewer allows you to view the SharePoint logs and filter their results with ease, meaning that you’ll be less hesitant to use them to troubleshoot. The log files are especially useful for debugging InfoPath form errors (just filter results to Forms Services), which are commonly used with Workflows. The logs also let you debug errors that occur before the workflow actually activates, or after it’s completed running. I’m not 100% sure who wrote this feature, but I think it was Scott Hillier.

A software engineer by trade, with a Masters degree in eCommerce, I focus on delivering end-to-end business solutions. ...and SharePoint's my platform.

Tagged with: , , , , , , , , , ,
Posted in C#.Net, SharePoint 2007, Visual Studio 2008, Workflow
3 comments on “Digging Deep – A Guide to Debugging SharePoint Workflows
  1. J. Cockrum says:

    Great article. Got me up and debugging workflows remotely, which was a real challenge.

    One note – on the test server we have (running Windows Server 2003) – the GAC path is C:\WINDOWS\ASSEMBLY\GAC_MSIL\YourAssemblyNameHere\version_PublicKeyToken

    Other than that – it was spot on and made a world of sense.

  2. K says:

    Great post. Saved me good deal of time.

  3. Daniel Westerdale says:

    Good post

    iisapp.exe is now longer available with installation of IIS7 so instead you’ll need:

    %windir%\system32\inetsrv\appcmd.exe list wp

    Incidentally, I wrote a post on my wp blog this week which was full of backslashes so it cd be your version of wp. Let me know if want to test any of your posts.

Comments are closed.

WordPress doesn’t like file paths
I'm having a bit of a problem with file paths. It seems that WP is automatically stripping out any backslash '\' characters that I use in my posts. I'm working on fixing this but it's a long (and boring) process. Thanks for being patient with this one. - fodi
Archives
Blog Stats
  • 62,086 hits