Sherlock Hosk and the case of the annoying bug

”How often have I said to you that when you have eliminated the impossible, whatever remains,however improbable, must be the truth?”

Sherlock Holmes Quote

-The Sign of Four

When debugging, eliminate what isn’t causing the problem and whatever code or customization is left must be the culprit.  – Sherlock Hosk

 

I was working on a bug today and I thought I would write a blog about my investigative process.

I had an entity called workshop, in the workshop it had an html grid of another entity maintenance items.

When you selected an item on the grid, it used OData to update the values on the item.

The maintenance item had two values I’m interested in

  • Selected
  • Manually selected

when I ticked the item, if it wasn’t automatically selected then the manually selected item was set to true and selected sent to true,  The update being an OData call meant the update was instant.

I was viewing the items in another browser I could see the values were updated as expected.

The bug occurred when I saved the workshop something was setting the Manually selected item to false.

What, How, Who

Good developers should ask why five times, I certainly did

WHY, WHY, WHY, WHY, WHY are you doing this to meeeee

So here is how I tracked down the bug

Auditing

Auditing is not a method for bug finding I use very often, I can usually find the problem in the code but I turned auditing on because I wasn’t sure what values were being changed and what was changing the values.

Auditing will show all the changes of fields (assuming you have turned the correct settings), to get an overview of auditing read  a Quick overview of auditing

I was not changing any field values using the GUI but you can never be sure what Javascript/plugins or workflows might be updating fields.

Plugins can update the values either by running as the user or running as a specified user.  In this project the plugins were running as a specified user.  The most common reason a user is chosen is because the chosen user has elevated privileges need to update related records.  Using a specific user means you don’t need to give those privileges to individual or teams of users.

Plugins

I checked what plugins were being triggered.

The plugin would have been triggered on the update event.

I did this by opening the Plugin Registration tool, changed the view to sort by entity and see what plugins are updated on the Workshop update.

When you find the plugins which are triggered you then need to check the plugin filters to see what field changes would trigger a plugin to run

I checked the plugin triggers for the maintenance item as well but this also didn’t have any plugins triggered to change those values.

I searched for the field being changed and it only occurred in a create plugin event, so I knew it definitely wasn’t being triggred.

Workflows

No workflows were being triggered

Javascript

Javascript has three main triggers

  • OnLoad – Form Level
  • OnSave – Form level
  • OnChange – Field level

The OnLoad and OnSave events are triggered when a form is loaded and when a form is saved.  OnChange event is triggered when a field value is changed

I checked the OnSave event and there wasn’t anything which seemed to be updating the values.

I wasn’t changing workshop form values so the OnChange event wasn’t the cause.

Business Rules

This is CRM 2011 system, so there is no such things as business rules here

What now Sherlock?

The sherlock quote from the start comes to mind.

 ”How often have I said to you that when you have eliminated the impossible, whatever remains,however improbable, must be the truth?”

Often when I am stuck on a bug, I find it helps to explain to myself what I know to be true

  • The flow of the code
  • What I know isn’t causing the bug
  • think what else could it be or how can I tackle this differently

The one piece of advice I would give to a junior developer when it comes to bug finding

When finding a bug, change one parameter/field at a time and then test again

The flow of code

  • The item maintenance item was changing and updating successfully when clicked
  • When I pressed the save button and the form reloading the value was changing
  • A plugin was not being triggered
  • There were no workflows
  • The OnSave Javascript was not updating the values
  • No Javascript OnChange event was being triggered

So to quote Sherlock Hosk

When debugging, eliminate what isn’t causing the problem and whatever code or customization is left must be the culprit.  – Sherlock Hosk

The only code left was the Javascript OnLoad

The Game is afoot

Before I go any further, you can buy those beautiful cuff links here for £12, awesome

To test if this was the problem when I saved the workshop I did a Save and Close, which stopped the Javascript Onload from being triggered

Hey presto, the field didn’t update.

I laid a Javascript debugger trap and finally found the code and fixed it.  Gave it a darn good testing and marked the bug as fixed for some futher testing.

Complex code?

 I wrote recently about complex customization in CRM

The problems with complex code and complex CRM Customizations

In this example I would say the complexity has been controlled.

  • All the plugins were filtered to only be triggered when certain fields changed
  • There were not lots of different customizations overlapping and triggering each other
  • The code was structured and logical, I could easily find the code I was interested in

You could argue OnLoad events triggering instant OData queries are slightly confusing/unexpected.

I hope you find this blog post interesting