If you’ve spent time writing ServiceNow Script Includes, you’ve probably run into the classic issue of checking for errors when working with GlideRecord. Normally, you’d write code like this:
var gr = new GlideRecord('incident');
gr.short_description = 'Test Incident';
if (!gr.insert()) {
gs.error('Failed to insert: ' + gr.getLastErrorMessage());
}
While this works, it’s easy to miss error handling, especially in larger scripts, and the logic for checking success/failure can get repetitive.
Introducing Exception-Based Error Handling
A cleaner way is to wrap operations in a utility that throws exceptions when something goes wrong. This shifts the paradigm from checking return values to letting the code fail fast and be handled by higher-level logic.
Why This is Better
- Consistency: Every insert, update, or other critical operation behaves the same way.
- Readability: Code flows without repeated
if (!success)checks. - Debugging: Exceptions can carry rich information about the error and context.
- Scoped Safety: Works well in custom scoped applications where cross-scope operations may complicate traditional checks.
Example: Exception-Throwing Wrapper
Here’s a small helper that wraps GlideRecord operations:
var GRHelper = Class.create();
GRHelper.prototype = {
initialize: function(gr) {
if (!(gr instanceof GlideRecord)) {
throw new Error('Expected a GlideRecord instance');
}
this.gr = gr;
},
insertOrThrow: function() {
var sysId = this.gr.insert();
if (!sysId) {
throw new Error('Insert failed: ' + this.gr.getLastErrorMessage());
}
return sysId;
},
updateOrThrow: function() {
var success = this.gr.update();
if (!success) {
throw new Error('Update failed: ' + this.gr.getLastErrorMessage());
}
return success;
},
deleteOrThrow: function() {
var success = this.gr.deleteRecord();
if (!success) {
throw new Error('Delete failed: ' + this.gr.getLastErrorMessage());
}
return success;
}
};
Using the Wrapper
try {
var gr = new GlideRecord('incident');
gr.initialize();
gr.short_description = 'Test Incident';
var sysId = new GRHelper(gr).insertOrThrow();
gs.info('Inserted incident: ' + sysId);
} catch (ex) {
gs.error('Error occurred: ' + ex.message);
}
Benefits in Real Projects
- Centralized Error Handling: You can customize your exception class to include error codes, variable names, or stack info. You can let it bubble up from a lower script include to a (e.g.,) scripted REST API handler.
- Improved Maintainability: Less repetitive boilerplate for every GlideRecord operation.
- Encourages Best Practices: By enforcing exceptions, you make it less likely to ignore errors silently.
Wrap-Up
If you’re working on custom scoped applications in ServiceNow, moving from return-value error checking to exception-based handling can make your scripts cleaner, more reliable, and easier to maintain. Wrapping GlideRecord operations in helper methods or a dedicated utility class lets you fail fast and respond to errors in a structured way, improving both code quality and application stability.
Leave a Reply