Skip navigation

Developer Community

1 Post authored by: Brad Simmons Employee

RogueOnBridgeCropped.png

The very first incident I worked as a ServiceNow support engineer is an interesting subject for any customization effort; don't just code for what a mentor of mine called the "Happy Path."

 

Consider what happens if things don't go as you expect.

There is nothing quite like trying to understand why your code isn't working only to find out after much debugging that it really was working but just not quite how you expected. 

 

See the new javascript debugger available beginning with the Dublin release.

 

 

Rogue 2006-2015 On one of his "Happy Paths"

 

In brief, a query for a specific record in a script did not find a result. (See Scripting in ServiceNow.) The script's author did not account for this and thus the data from the previous iteration was used populating an incident with incorrect data.

 

In detail, a custom email inbound action, System Policy > Inbound Actions, "Some_Clever_InBound_Email_Script_Name" existed and in that script we find a query for a user as follows:

 

var userLookup = new GlideRecord('sys_user');
userLookup.addQuery('email', email.from);
userLookup.query();

while (usrlookup.next())
{
  var userID = userLookup.sys_id;
}
                            

 

Yesterday, on the plane, I saw a guy in his Seahawks jersey and hat.  It is not even close to football season but it got me fired up.  Thus explains some of the sample data I use below.

 

For great information on Email including Inbound Actions see Katharine Campbell's blog posts found here, Email, Email, and More Email

 

If the above "userlookup.query();" fails to find the record, then the loop is not entered and the userID will not be set.  In fact, it could have data from the previous run of the script or simply be undefined.  In this particular case the email came from marshawn.lynch[@]seahawks.com but in his user record his email is listed as beastmode[@]seahawks.com.  So of course no match was found.

 

Later in the script, userID is used to set opened_by on an incident and the customer was surprised to find that the data said the incident was opened by russell.wilson[@]seahawks.com When we looked into the details we found that the previous email processed was from russell.wilson[@]seahawks.com (oops!).

 

To fix this issue you can modify your script to set the userID to null or to some default user before using the result of the lookup query.

 

var userID = 'pete.carroll@seahawks.com';
while (usrlookup.next()){
  userID = usrlookup.sys_id;
}
                      

 

Or put the lookup in an "if-else" rather then a while:

 

if (userlookup.next()){
  var userID = userlookup.sys_id;
} else{
  var userID = 'pete.carroll@seahawks.com';
}
                      

 

Your choice will vary depending on your business needs; whether you use a default user or some other action, if the user lookup fails to find a record you want to make sure you account for that not so Happy Path.  Additionally, you might need to consider what you would do if more then one record is found.

 

Other areas where I have seen the "Happy Path" cause issues:

  1. "While it never happened"  - Use of a while loop without considering what to do when the loop is not entered.
  2. "Pass it to me" - When you write a function consider what will happen if the caller passes you bad data.
  3. "Bad returns" - When you call a function but don't get back what you expected.
  4. "Talk to me" - When you log a certain condition but don't log when the condition doesn't occur.

 

And finally:  "Undefined is not fine" -  This one caused a P1 incident last week.  A Glide Scriptable was being called:

 

var enc = new GlideEncrypter();
var encryptedString = enc.encrypt(source.u_stringToEncrypt);
                   

 

But source.u_stringToEncrypt was undefined.  GlideEncrypter eventually tried to make a copy of source.u_stringToEncrypt and since this string was undefined it pointed to some random place in memory.  And with nothing to terminate the string it copied and copied and copied and copied until the JVM ran out of memory.  (See #2 above.  I have submitted a problem report.)

 

When scripting in your customizations be sure to always be ready to react if you don't get what you want.  Just as Russell Wilson always has an audible ready if he doesn't get the defensive look he wants.

 

Go Hawks!

Filter Blog

By date: By tag: