WORKAROUND/HOW-TO: Write Exception Messages to Workflow History List as Makeshift Error Log for Troubleshooting Sand Boxed Solutions

2012-09-06 MV: In my current (cool) project we are highly constrained in the SharePoint PROD farm – NO server access, but we DO get to deploy “sandboxed” (restricted) solutions…

Which begs the question: HOW do I write error messages in (say) my try-catch blocks, so I can troubleshoot my solutions?

  • I CAN’T write to the Visual Studio 2010 console  – I need the error messages generated when the solution is in the PROD environment;
  • I CAN’T write to the /14/logs logfiles – I don’t have RDC (Remote Desktop Client) access to any of the PROD servers;
  • I CAN’T write to the .NET MessageBox class (e.g. MessageBox.Show(ex.Message) ) – at least not thus far;
  • I CAN’T write to (say) a javascript alert() window, because my code is executing on the SERVERS (not browsers);
  • I CAN’T make a new list to write to, because of security restrictions;

Well, what I CAN do is this – WRITE TO THE (closest) WORKFLOW HISTORY LIST !

:-)

  • It’s always there;
  • It’s always in a predictable location (./{yourwebsite}/lists/workflow history);
  • It’s always got precisely the same name;
  • It already has ALL the fields you’d use IF you COULD build your OWN custom error log (list).

:-)

Here’s some example code taken from a WORKING solution:


public override void ItemAdded(SPItemEventProperties properties)
 {
 base.ItemAdded(properties);

//CONDITION FOR LIST...
 if (properties.ListTitle == "Datamap")
 {
 try
 {
 //get the current list item...
 currentItem = properties.ListItem;
 //get the target list...
 currentWeb = properties.OpenWeb();
 targetList = currentWeb.Lists["IPT CourtUnits"];
 //create a new (empty) entry in the target list...
 newListItem = targetList.Items.Add();
 //populate key fields of the new entry...
 newListItem["IPT_State"] = currentItem["State"];
 newListItem["IPT_City"] = currentItem["City"];
 newListItem["IPT_Address"] = currentItem["Address"];
 newListItem["IPT_CourtType"] = currentItem["Court Type"];
 //update the new entry...
 newListItem.Update();
 }
 catch (Exception ex)
 {
 String errorLogEntry = ex.Message;
 WriteToLog(properties, errorLogEntry);
 }
 }
 }

public void WriteToLog(SPItemEventProperties properties, String LogEntry)
 {
 //this helper function writes to the existing Workflow History List in lieu of writing to the inaccessible /14/logs files...
 currentWeb = properties.OpenWeb();
 //get the Workflow History List for this site...
 workflowHistoryList = currentWeb.Lists["Workflow History"];
 //create a new entry in the list...
 newWorkflowListItem = workflowHistoryList.Items.Add();
 //populate the fields of this new item...
 newWorkflowListItem["Date Occurred"] = DateTime.Now;
 newWorkflowListItem["Title"] = "ER ERROR";
 newWorkflowListItem["Description"] = LogEntry;
 //update the new list item...
 newWorkflowListItem.Update();
 }

Hope some of you finding yourselves coding sandboxed solutions in highly-restrictive environments find this useful.

Peace,

-MV

Leave a Reply

Your email address will not be published. Required fields are marked *