gs.getProperty() - avoiding Lost Property [ServiceNow]

Personally, there are a couple of things I don’t like about gs.getProperty() ....
The ServiceNow GlideSystem method gs.getProperty() is a frequently used function to store configurations outside of the code. This is best practice.
It returns null if the property doesn’t exist (or you can specify a default value). So what don't I like and why? I think it encourages the following issues, particularly for larger codebases:
Often, a property might actually be mandatory, but the code does not check for its existence, and the hope is that the 'null' value will somehow get caught by some later bit of code before too much harm has been done.
It encourages the design of 'optional' properties. Which then :
- must be documented outside of the delivered implementation, otherwise they can become lost, invisible and almost 'secret' knowledge.
- create an additional code path to be tested
I tend to code quite defensively by default, so I will usually throw an error if a property doesn't exist. This helps to ensure the property is kept with the code base, is self-documenting, and it's less likely to get omitted during a migration, etc.
var someValue = gs.getProperty('somePropertyName');
if (someValue === null) {
throw new Error(‘Property not found’);
}
Usually, I write a small function, e.g. getProp(), at the application level. I avoid calling it getProprerty() so it doesn't get confused with the original gs.getProperty() function.
/**
* Get a property throw an exception if it doesnt exist.
* @param {string} propName - the property Name
* @returns {string} the property value
*/
function getProp(propName) {
var propVal = gs.getProperty(propName);
if (propVal === null) {
throw new Error('Property does not exist: '+propName);
}
return propVal;
}
var someValue = getProp('somePropertyName');
I usually add the option to pass through the default value too so it's a drop-in replacement for gs.getProperty():
/**
* Get a property throw an exception if it doesnt exist.
* @param {string} propName - the property Name
* @param {string} defaultVal - a default value
* @returns {string} the property value
*/
function getProp(propName) {
var propVal = gs.getProperty(propName,defaultVal);
if (defaultVal === undefined && propVal === null) {
throw new Error('Property does not exist: '+propName);
}
return propVal;
}
There are other considerations with system properties that I might blog about sometime:
Property names should give a clue as to what might be impacted by changing them. Particularly, global properties which do not have the benefit of a scope prefix to indicate impact.
If creating many similar properties, sometimes it is better to create a lookup (extend Data Lookup [dl_matcher])
Often it is recommended to move code constants to system properties - but if changing that constant will fundamentally break/change the code, then sometimes it is best left as a named constant, or Script Include property - rather than unnecessarily exposed as a system property.
Subscribe to my newsletter
Read articles from Andy Lord directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
