4
votes

I recently migrated a Sharepoint 2010 site to Sharepoint 2013, since then my customized workflows developed in Visual Studio that works perfectly for 2 years without a glitch suddenly after the migration it started throwing this exception.

w3wp.exe (0x4D3C)                           0x10F0  SharePoint Foundation           Legacy Workflow Infrastructure  88xr    Unexpected
WinWF Internal Error, terminating workflow Id# 21492445-9c27-479c-ae16-5d0d3ae84b69 

w3wp.exe (0x4D3C)                           0x10F0  SharePoint Foundation           Legacy Workflow Infrastructure  98d4    Unexpected
Microsoft.SharePoint.SPException: Cannot complete this action.  Please try again. ---> System.Runtime.InteropServices.COMException: Cannot complete this action.  
Please try again.<nativehr>0x80004005</nativehr><nativestack></nativestack>     
at Microsoft.SharePoint.Library.SPRequestInternalClass.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bPreserveItemUIVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bUnRestrictedUpdateInProgress, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback)     
at Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bPreserveItemUIVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bUnRestrictedUpdateInProgress, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback)     
--- End of inner exception stack trace ---     
at Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx)     
at Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bPreserveItemUIVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bUnRestrictedUpdateInProgress, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback)     
at Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, Boolean bPreserveItemVersion, Boolean bNoVersion, Boolean bMigration, Boolean bPublish, Boolean bCheckOut, Boolean bCheckin, Guid newGuidOnAdd, Int32& ulID, Object& objAttachmentNames, Object& objAttachmentContents, Boolean suppressAfterEvents, String filename, Boolean bPreserveItemUIVersion)     
at Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration, Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents, String filename, Boolean bPreserveItemUIVersion)     
at Microsoft.SharePoint.SPListItem.Update()     
at ProductList.AutoApprovalProcess.ApprovalWorkflow.AuthorizeItem()     
at ProductList.AutoApprovalProcess.ApprovalWorkflow.onWorkflowActivated1_Invoked(Object sender, ExternalDataEventArgs e)     
at System.Workflow.ComponentModel.Activity.RaiseGenericEvent[T](DependencyProperty dependencyEvent, Object sender, T e)     
at System.Workflow.Activities.HandleExternalEventActivity.RaiseEvent(Object[] args)     
at System.Workflow.Activities.HandleExternalEventActivity.Execute(ActivityExecutionContext executionContext)     
at System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)     
at System.Workflow.ComponentModel.ActivityExecutorOperation.Run(IWorkflowCoreRuntime workflowCoreRuntime)     
at System.Workflow.Runtime.Scheduler.Run()

I looked at my codes and see what exactly happens on ApprovalWorkflow.AuthorizeItem() then its nothing really fancy, here is what it does

private void AuthorizeItem()
{
    workflowProperties.Item.ModerationInformation.Status = SPModerationStatusType.Approved;
    workflowProperties.Item.Update();
}

Basically the workflow just auto approves the item based on a certain condition it meets. What I then see in the Workflow information is this

enter image description here

which it thrown by ActivityExceutionStatus

protected override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
{
    ((ISharePointService)executionContext.GetService(typeof(ISharePointService))).LogToHistoryList(base.WorkflowInstanceId, SPWorkflowHistoryEventType.WorkflowComment, 0, TimeSpan.MinValue, string.Empty, string.Format("WorkFlow Exception!: {0}", exception.Message), string.Empty);
    return ActivityExecutionStatus.Closed;
}

Take note this does not happen everytime the workflow is invoked, it happens on occasions I dont know what triggers

Does anyone have an idea what causes this and how to prevent it from happening again?

Update 1 Actual Codes added below for clarity

public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
pblic enum ThresholdItem { MultipleThreshold, NoThreshold, BelowThreshold, AboveThreshold, Valid };

private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
    switch (ThresholdCheck())
    {
        case ThresholdItem.Valid:
            AuthorizeItem();
            break;
        case ThresholdItem.BelowThreshold:
            RequestDenied("Below Threshold");
            break;
        case ThresholdItem.AboveThreshold:
            RequestDenied("Above Threshold");
            break;
        case ThresholdItem.NoThreshold:
            RequestDenied("No Threshold Defined");
            break;
        case ThresholdItem.MultipleThreshold:
            RequestDenied("Multiple Threshold Defined");
            break;
    }
}   


private ThresholdItem ThresholdCheck()
{
    SPLinqDataContext dc = new SPLinqDataContext(workflowProperties.SiteUrl + "/Testing");

    EntityList<ThresholdsItem> PriceThreshold = dc.GetList<ThresholdsItem>("Thresholds");

    string destination = GetLinkedListItemString(workflowProperties.Item["Destination"].ToString());
    string origin = GetLinkedListItemString(workflowProperties.Item["Origin"].ToString());
    double price = double.Parse(workflowProperties.Item["Price"].ToString());

    var Result = (from p in Threshold
                    where
                        p.Destination.Title == destination &&
                        p.Origin.Title == origin
                    select p);
    switch (Result.Count())
    {
        case 1:
            var SingleResult = Result.SingleOrDefault();
            if (SingleResult.MinPrice > price)
                return ThresholdItem.BelowThreshold;
            else if (SingleResult.MaxPrice < price)
                return ThresholdItem.AboveThreshold;
            else
                return ThresholdItem.Valid;
        case 0:
            return ThresholdItem.NoThreshold;

        default:
            return ThresholdItem.MultipleThreshold;

    }
}

private void RequestDenied(string note)
{
    workflowProperties.Item.ModerationInformation.Status = SPModerationStatusType.Denied;
    workflowProperties.Item.ModerationInformation.Comment = note;
    workflowProperties.Item.Update();
}

private string GetLinkedListItemString(string item)
{
    if (item.Contains("#"))
    {
        return sItem.Substring(item.LastIndexOf("#") + 1);
    }
    else
    {
        return item;
    }
}
1
The reason why it happens infrequently might be because it checks for some value (not sure how you are using the WF) and that value is null.Ola Ekdahl
This them brings me to my question why it worked on the old Sharepoint without a glitch for more than 2 years, this just happened when we migrated.Raymund
Is there any useful info in the ULS log?Ola Ekdahl

1 Answers

3
votes

Ok it seems like I found the issue and it is in the code itself if you read it closely. Hopefully this solution would help someone in the future.

What happens is that the workflow goes on a multiple loop, this happens when the user updates the list item, it triggers to run the workflow. What happens next is that the Workflow Worker Thread moderates the item and set it to approved, this in turn again triggers the workflow, then it goes again and again until SharePoint decides to terminate it? (not sure yet how but I notice it only runs 10 times). What I noticed is that Sharepoint 2010 handles it very well but Sharepoint 2013 does not and throws and exception once in a while.

If you look at the image it run 10 times (the red highlighted item) before but after fixing it, I tried it twice and now it runs as expected (the blue and green highlighted items).

So whats the fix for the update process not to trigger the workflow again and I had done that by following this solution: https://stackoverflow.com/a/2468156/412519

then change my Updates to

workflowProperties.Item.Update(true);

enter image description here