Logging SharePoint Workflow Errors in Workflow History

The workflow history in a SharePoint list will display error events with not so helpful messages like "An error occured in "SomeWorkflow." This will almost certainly make one grimace with the task of opening the event viewer or digging into the 12 hive error logs to find out went wrong.

I've found it useful to log the errors to a comment in the workflow history. It presents immediate feedback when testing a workflow.


Drop the following code in your workflow code.

-------------------------------

// Log any exception
// Override the HandleFault handler


protected override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
{
LogErrorToHistoryList(executionContext, exception.Message);
return base.HandleFault(executionContext, exception);

}

//You can also call this method from anywhere in code.
//This code programatically runs a LogToHistory activity.

private void LogErrorToHistoryList(ActivityExecutionContext executionContext, string errorMsg)
{

((ISharePointService)executionContext.GetService(typeof(ISharePointService))).LogToHistoryList(base.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, 0, TimeSpan.MinValue, string.Empty, string.Format("Error in workflow! {0}", errorMsg), string.Empty);

}


-----------------------------
In the event of an exception the workflow history comments will show two entries. One entry will say "An error has occured in SomeWorkflowName" and the other could say something like: "Error in Workflow! Correlation value specified does not match the already initialized correlation value on declaration TaskToken for activity sendEmailToApprover. "


In matter of Sharepoint seconds one can know where to look first.

References:

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

2 comments:

Kevin said...

This is great but to call LogErrorToHistoryList directly from my own error handlers, how to I generate the ActivityExecutionContext argument.

Joe Loftus said...

Every Activity in WF has an execution context including child activities. This is not unlike the HTTP Context object in an ASP.net application. The execution context has a state, parameters, properties that are unique.

The WF engine rehydrates the activity when the workflow is activated and will therefore have a context. If you have a fault handler on an activity the context will be available to you.

In WF The 'sender' object can be cast as a context using


ActivityExecutionContext ctx = sender as ActivityExecutionContext;

or you can create your own from an existing enabled activity using the execution context manager.

Activity act = EnabledActivities[0];

ActivityExecutionContext newContext =
parentCtx.ExecutionContextManager.CreateExecutionContext(act);



References:

Activity State Model
http://msdn.microsoft.com/en-us/library/aa718190.aspx

Here is an MSDN Article worth reading
http://msdn.microsoft.com/en-us/magazine/cc163414.aspx

Hope this helps

Joe