REST API Custom Error Response

Kiran Patil3
Giga Expert

Hi,

We are trying to add custom response on mandatory variable check-in record producer REST API.

Here is the code for the custom error message:

(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
	
	var recordProducerId = request.pathParams.sys_id;
	var request_body = request.body.nextEntry();
	var noValidation =  (request_body.sysparm_no_validation == 'true');
	
	var catalogUtil = new RestCatalogUtil();
	var isMobile = false;
	
	
	if (request.queryParams.sysparm_view) {
		var viewType = '' + request.queryParams.sysparm_view;
		viewType = viewType.toLowerCase();
		if(viewType == 'mobile')
			isMobile = true;
	}
	
	if(!catalogUtil.isValidItem(recordProducerId, 'sc_cat_item_producer'))
		throw new sn_ws_err.NotFoundError('Record Producer does not exists');
	
	var catalogItem = new sn_sc.CatItem(recordProducerId);
	
	if(!catalogItem.canView(isMobile))
		throw new sn_ws_err.BadRequestError("Security Constraints prevent access to the Item");
	
	var variables = request_body.variables || {};
		
		variables = prePopulateVariables(recordProducerId, variables);
		
		gs.info("Here is the variabbles: " + JSON.stringify(variables));
		
		if (!noValidation) {
			//Mandatory Variables Check
			if(!catalogUtil.checkMandatoryVariables(recordProducerId, variables))
				{
				//	var varInput = [];
				//varInput.push(JSONParser(variables));
				var mandatoryError = new sn_ws_err.ServiceError();
				mandatoryError.setStatus(400);
				mandatoryError.setMessage('Mandatory variables are not filled');
				mandatoryError.setDetail(JSON.stringify(variables));
				throw mandatoryError;
			}
				//throw new sn_ws_err.BadRequestError('One or more mandatory variables are invalid or empty: '+variables);
		}
		
		request_body.sysparm_id = recordProducerId;
		request_body.sysparm_action = 'execute_producer';
		if (!request_body.sysparm_item_guid)
			request_body.sysparm_item_guid = gs.generateGUID('');
		
		return catalogItem.submitProducer(request_body);
		
		
	})(request, response);
	
	
	function prePopulateVariables(itemId, variables) {
		variables = variables || {};
			var varGr = new GlideRecord('item_option_new');
			var qr = varGr.addQuery('cat_item', itemId);
			var variableSet = new sn_sc.CatItem(itemId).getVariableSet();
			if(variableSet.length > 0)
				qr.addOrCondition("variable_set", variableSet);
			varGr.addActiveQuery();
			varGr.query();
			while(varGr.next()) {
				if(varGr.type == 8 && !gs.nil(variables[varGr.getValue('name')])){
					var varValue = variables[varGr.getValue('name')];
					var query = '';
					if(!gs.nil(variables[varGr.getValue('name') + '_lookup_field']))
						{
						query = variables[varGr.getValue('name') + '_lookup_field'] + "=" + varValue;
					} else {
						query = "sys_id=" + varValue;
						query += "^ORuser_name=" + varValue;
						query += "^ORnumber=" + varValue;
						query += "^ORname=" + varValue;
					}
					
					variables[varGr.getValue('name')] = getRecordSysId(varGr.reference, query);
					
				}
				
				if(varGr.type == 21 && !gs.nil(variables[varGr.getValue('name')])){
					var varValue = variables[varGr.getValue('name')];
					var query = '';
					if(!gs.nil(variables[varGr.getValue('name') + '_lookup_field']))
						{
						query = variables[varGr.getValue('name') + '_lookup_field'] + "IN" + varValue;
					} else {
						query = "sys_idIN" + varValue;
						query += "^ORuser_nameIN" + varValue;
						query += "^ORnumberIN" + varValue;
						query += "^ORnameIN" + varValue;
					}
					
					variables[varGr.getValue('name')] = getRecordSysIdList(varGr.list_table, query);
					
				}
			}
			
			return variables;
		}
		
		function getRecordSysId(table_name, encoded_query) {
			gs.info("Here is the encoded_query: " + table_name + ' ' + encoded_query);
			
			var gr = new GlideRecord(table_name);
			gr.addEncodedQuery(encoded_query);
			gr.setLimit(1);
			gr.query();
			
			if(gr.next()){
				return gr.getValue("sys_id");
			}
			else {
				return '';
			}
		}
		
		function getRecordSysIdList(table_name, encoded_query) {
			gs.info("Here is the encoded_query: " + table_name + ' ' + encoded_query);
			
			var sys_id_list = [];
			var gr = new GlideRecord(table_name);
			gr.addEncodedQuery(encoded_query);
			gr.query();
			
			gs.info("Here is the count " + gr.getRowCount());
			
			while(gr.next()){
				
				sys_id_list.push(gr.getValue("sys_id"));
			}
			
			gs.info("Here is the sys_id_list.join(): " + sys_id_list.join());
			
			return sys_id_list.join();
		}
		

Response in postman as follows:

{
    "error": {
        "message": "Mandatory variables are not filled",
        "detail": "{\"username\":\"\",\"disable_account_true\":\"true\",\"justification\":\"Test\",\"opened_by\":\"fdf1dfe71b527fc4d98f3153cd4bwer3\"}"
    },
    "status": "failure"
}

I have added variables back in detail of the response so end-user would know what variables had invalid input or empty value however JSON.stringify would add an extra backslash to response which is annoying. I have tried JSON.parse as well but JSON.parse is not supported in the scoped application, I think.

Please help if anyone has faced a similar kind of issue in the past and fixed it.

Thanks in advance.

~ Kiran

4 REPLIES 4

Tony Chatfield1
Kilo Patron

Hi, I would guess the \ chars are the result of the "char" being escaped;
can you create your object with 'single quotes'

Hi Tony,

Object is return from below (OOB) function

variables = prePopulateVariables(recordProducerId, variables);

this function already returning as JSON object. Not sure how can I stringify JOSN object within another object.

Tony Chatfield1
Kilo Patron
I am not aware of anyway to change the default text identifier. If no one responds with a solution can you run a regex over the string before presenting it to the users?

Yes, regex is my last option 🙂