Name
sn_hr_core.ErrorUtil
Description
No description available
Script
/**
* @Constructor
*/
function ErrorUtil() {
this._formatUtil = new sn_hr_core.FormatUtil();
}
ErrorUtil.ERROR_KEY = '***~Error';
ErrorUtil.HR_METHOD_NAME = 'ErrorMethodName';
ErrorUtil.METHOD_NAME_SEPARATOR = ': ';
ErrorUtil.METHOD_MSG_SEPARATOR = ' ## ';
ErrorUtil.INSERT = 'insert';
ErrorUtil.UPDATE = 'update';
ErrorUtil.DELETE = 'delete';
ErrorUtil.QUERY = 'query';
/**
* Method to be used when throwing an exception. To get an error object from the message. This method logs the
* message and returns an Error object.
*
* @param {string} message - The error message.
*
* @return {Error} - The error object.
*/
ErrorUtil.prototype.getError = function(message) {
return new Error(message);
};
/**
* Method to be used in a catch block. This method adds the method name to the log message, logs the error message
* and returns an Error object that the caller can use to throw an exception.
*
* @param {string} methodName - The method name in which this method is being used.
*
* @param {Error} caughtError - The error object that was caught in the exception.
*
* @return {Error} - The error object
*/
ErrorUtil.prototype.handleExceptionMethod = function(methodName, caughtError) {
return this.handleException(methodName, null, caughtError);
};
/**
* Method to be used in a catch block. This method adds the method name to the log message, logs the error message
* and returns an Error object that the caller can use to throw an exception.
*
* @param {string} methodName - The method name in which this method is being used.
*
* @param {string|null} message - The error message.
*
* @param {Error} caughtError - The error object that was caught in the exception.
*
* @return {Error} - The error object.
*/
ErrorUtil.prototype.handleException = function(methodName, message, caughtError) {
var origMessage = this.getMessageFromError(caughtError);
var newMessage = this._getMethodNameMessage(methodName, origMessage);
// If the message in the caught error already has the keyword, ErrorUtil.ERROR_KEY, then we do not want to use
// the value of 'message'. We only want to use the error message that was originally set. We do not want to
// prepend an additional messages that were passed to this method in additional catch blocks
if (!newMessage.includes(ErrorUtil.ERROR_KEY) && !gs.nil(message))
newMessage = ErrorUtil.ERROR_KEY + ': ' + message + '\n' + newMessage;
newMessage += this._getSourceName(caughtError);
newMessage += this._getErrorObjKeyValue(caughtError, 'lineNumber');
return new Error(newMessage);
};
/**
* Method that helps to get error message from he error object. The error object can either be an Error or Java
* Exception. Depending upon the type of the object, the way to retrieve the error message is different.
*
* @param {Error} error - The error object.
*
* @return {string} - The error message.
*/
ErrorUtil.prototype.getMessageFromError = function(error) {
try {
if (!gs.nil(error.message))
return error.message + '';
} catch (error) {
// Sometimes error object does not contain message and it throws an exception
}
return error + '';
};
/**
* Checks if a record exists for the given glide record.
*
* @param {GlideRecord} glideRecord - Glide record that needs to be checked
*
* Throws an exception if there is an error or if hasNext returned false
*/
ErrorUtil.prototype.validateRecordExist = function(glideRecord) {
this.validateGrForError(glideRecord);
this.throwOnRecordNotFound(glideRecord);
};
ErrorUtil.prototype.throwOnRecordNotFound = function(glideRecord) {
if (!glideRecord.hasNext())
throw this.getError('No record found in the table ' + glideRecord.getTableName() + ' for the query string: ' +
glideRecord.getEncodedQuery());
};
/**
* Validates if there is any error when querying the glide record or if the record exists or not.
*
* A note about GlideRecord::query method. Even though a query business rule fails, the glide record query hasNext()
* will return true and one get all the values. For example, when the following query is run in the back-ground
* script
*
* var glideRecord = new GlideRecord('sys_user');
* glideRecord.addQuery('sys_id', 'f6911038530360100999ddeeff7b12b3');
* glideRecord.query();
* gs.info('HasNext: ' + glideRecord.hasNext())
* glideRecord.next();
* gs.info('UserName: ' + glideRecord.getValue('user_name'));
*
* Even though a BR validation failed, we still see in the output, the HasNext is true and we are able to do
* glideRecord.next() and then get the value of user_name field.
*
* Background message, type:error, message: Query validation failed.
* Operation against file 'sys_user' was aborted by Business Rule 'SysUserQueryBeforeBr^null'. Business Rule
* Stack:SysUserQueryBeforeBr
* sn_hr_core: HasNext: true sn_hr_core: UserName: arron.ubhi
*
*
* @param {GlideRecord} glideRecord - The glide record object on which the query has been made.
*/
ErrorUtil.prototype.validateGrForQuery = function(glideRecord) {
this.validateGrForError(glideRecord);
this.throwOnRecordNotFound(glideRecord);
};
/**
* Validates if glide record has any error or not.
*
* @param {GlideRecord} glideRecord - Glide record that has to be validated
*
* Throws an exception if glide.getLastErrorMessage is not null.
*/
ErrorUtil.prototype.validateGrForError = function(glideRecord) {
if (gs.nil(glideRecord.getLastErrorMessage()))
return;
throw this.getGrError(glideRecord);
};
ErrorUtil.prototype.throwGrError = function(glideRecord) {
throw this.getGrError(glideRecord);
};
ErrorUtil.prototype.getGrError = function(glideRecord) {
var errorMessage = '';
var operation = glideRecord.operation();
if (gs.nil(operation))
operation = ErrorUtil.QUERY;
errorMessage += 'Error with \'' + operation + '\' operation on the table \'' + glideRecord.getTableName() + '\'. ' +
this._getGrEncodedQuery(glideRecord) + this._getGrSetValues(operation, glideRecord) +
(gs.nil(glideRecord.getLastErrorMessage()) ? '' : '. ' + glideRecord.getLastErrorMessage());
return this.getError(errorMessage);
};
ErrorUtil.prototype.throwOnEmptyValue = function(paramName, paramValue) {
if (!gs.nil(paramValue))
return;
throw this.getError(this._formatUtil.format('The value for the \'{0}\' is null.', paramName));
};
ErrorUtil.prototype._getGrEncodedQuery = function(glideRecord) {
if (gs.nil(glideRecord.getEncodedQuery()))
return '';
return 'Query: \'' + glideRecord.getEncodedQuery() + '\' ';
};
ErrorUtil.prototype._getGrSetValues = function(operation, glideRecord) {
if (operation == ErrorUtil.DELETE)
return '';
var GR_SYSTEM_FIELDS = ['sys_updated_on', 'sys_class_name', 'sys_id', 'sys_updated_by', 'sys_created_on',
'sys_domain', 'sys_name', 'sys_scope', 'sys_created_by', 'sys_mod_count', 'active', 'sys_package',
'sys_update_name', 'sys_tags', 'calendar_integration', 'web_service_access_only', 'notification',
'enable_multifactor_authn', 'internal_integration_user'
];
var elements = glideRecord.getElements();
var setValuesStr = '';
for (var idx = 0; idx < elements.length; ++idx) {
var element = elements[idx];
if (gs.nil(element.toString()) || GR_SYSTEM_FIELDS.indexOf(element.getName()) != -1)
continue;
if (!gs.nil(setValuesStr))
setValuesStr += ', ';
setValuesStr += element.getName() + '=' + element.toString();
}
return ', SetValues: \'' + setValuesStr + '\'';
};
ErrorUtil.prototype.type_of = function(value) {
if (value === null)
return 'null';
var t = typeof value;
if ((t == 'string') || (t == 'number') || (t == 'boolean') || (t == 'function'))
return t;
if ((value instanceof String) || ('' + value.constructor).match(/^function String\(\)/))
return 'string';
if (value instanceof Number)
return 'number';
if (value instanceof Boolean)
return 'boolean';
return 'object';
};
ErrorUtil.prototype._getErrorObjKeyValue = function(errorObj, keyName) {
var value = this._getErrorObjValue(errorObj, keyName);
if (gs.nil(value))
return '';
return ' ' + keyName + ': ' + value;
};
ErrorUtil.prototype._getErrorObjValue = function(errorObj, keyName) {
if (gs.nil(errorObj) || !(keyName in errorObj) || (typeof (errorObj[keyName]) === 'function'))
return '';
var value = errorObj[keyName];
if (gs.nil(value) || value === 0)
return '';
return value;
};
ErrorUtil.prototype._getSourceName = function(caughtError) {
var fileName = this._getErrorObjValue(caughtError, 'fileName');
var sourceName = this._getErrorObjValue(caughtError, 'sourceName');
if (gs.nil(fileName) && gs.nil(sourceName))
return '';
return fileName === sourceName ? (' Source: ' + fileName) : (' Source: ' + fileName + ' ' + sourceName);
};
ErrorUtil.prototype._getMethodNameMessage = function(methodName, message) {
try {
// The comments below explains what the messageArray will contain as entries after the split.
//
// If we consider the following error message:
//
// ***~Error: Error closing registration
// ErrorMethodName: Close Registration->updateRegistrationState->notifyRegistrationState ## Cannot find
// function getState in object [object GlideRecord].
//
// METHOD_MSG_SEPARATOR is ##. If we consider the above example, the messageArray will contain elements:
// messageArray[0] =
// ***~Error: Error closing registration
// ErrorMethodName: Close Registration->updateRegistrationState->notifyRegistrationState
// messageArray[1] = Cannot find function getState in object [object GlideRecord].
var messageArray = message.split(ErrorUtil.METHOD_MSG_SEPARATOR);
if (gs.nil(messageArray) || messageArray.length === 0)
return message;
// If the message array length is one, then it means that we have not added the method name info. until now. So,
// add it and return. The method name info is ErrorMethodName: Close Registration->updateRegistrationState->
// notifyRegistrationState
if (messageArray.length == 1)
return ErrorUtil.HR_METHOD_NAME + ErrorUtil.METHOD_NAME_SEPARATOR + methodName +
ErrorUtil.METHOD_MSG_SEPARATOR + message;
if (messageArray.length !== 2)
return ErrorUtil.HR_METHOD_NAME + ErrorUtil.METHOD_NAME_SEPARATOR + methodName +
ErrorUtil.METHOD_MSG_SEPARATOR + message;
var methodNameStrSplit = messageArray[0].split(ErrorUtil.METHOD_NAME_SEPARATOR);
return ErrorUtil.HR_METHOD_NAME + ErrorUtil.METHOD_NAME_SEPARATOR + methodName + '->' + methodNameStrSplit[1] +
ErrorUtil.METHOD_MSG_SEPARATOR + messageArray[1];
} catch (caughtError) {
return message;
}
};
Sys ID
1fecae6ffb8410101d696a7521706923