- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-17-2020 08:50 AM
I am working on a scoped application to store the service tickets generated on an another application. The application has custom tables for storing the service Tickets. The scoped application has scripted REST API to store the tickets.
The REST API iterates through the JSON input for tickets and stores them in to the custom table. When I am trying to insert batch of 2000 records, I am getting transaction time out error with maximum execution time exceeded. I can reduce the batch of tickets so that I do not get transaction time out error or increase the time out value for transaction quota.
However my question, is how to handle such platform errors in the Scripted REST API. I have tried enclosing the code in the try-catch however it looks like whenever "RESTRuntimeException" is thrown by platform the REST API does not get chance to handle the exception.
Sample code for scripted REST API:
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
try {
var inputData = request.body.data;
var tickets = inputData.tickets;
for (var i = 0; i <tickets.length; i++) {
// Code to insert the records
}
} catch (e) {
gs.error("Failed to process the request");
var serviceError = new sn_ws_err.ServiceError();
serviceError.setStatus(500);
serviceError.setMessage(e.message);
serviceError.setDetail("Failed to process request with error message: " + e.message);
response.setError(serviceError);
}
})(request, response);
Error Logs shows below stacktrace:
com.glide.rest.util.RESTRuntimeException: com.glide.rest.util.RESTRuntimeException: com.glide.rest.serializer.impl.JSONSerializer.handleSerializeException(JSONSerializer.java:166)
com.glide.rest.serializer.impl.JSONSerializer.serializeServiceResult(JSONSerializer.java:60)
com.glide.rest.handler.impl.ServiceResultHandlerImpl.serialize(ServiceResultHandlerImpl.java:130)
com.glide.rest.handler.impl.ServiceResultHandlerImpl.processServiceResultBody(ServiceResultHandlerImpl.java:96)
com.glide.rest.handler.impl.ServiceResultHandlerImpl.processServiceResult(ServiceResultHandlerImpl.java:40)
com.glide.rest.processors.RESTAPIProcessor.process(RESTAPIProcessor.java:291)
com.glide.processors.AProcessor.runProcessor(AProcessor.java:576)
com.glide.processors.AProcessor.processTransaction(AProcessor.java:264)
com.glide.processors.ProcessorRegistry.process0(ProcessorRegistry.java:181)
com.glide.processors.ProcessorRegistry.process(ProcessorRegistry.java:169)
com.glide.ui.GlideServletTransaction.process(GlideServletTransaction.java:44)
com.glide.sys.Transaction.run(Transaction.java:2228)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)
I am facing two issue because of this platform behaviour
1. Since error is not handled by the REST APIs, I am not able to return custom error response to the client
2. Part of the batch records are persisted successfully and part of the batch records are not persisted. However since client has received 500 error code, client has no clue about successfully persisted records.
Appreciate any help on this.
Thanks
Ashutosh
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-18-2020 07:53 PM
Discussed this case with ServiceNow support as well.
The platform behaviour is as designed. The support team responded that the Transaction time out error with maximum execution time exceeded is an application level error, platform cannot handled it at javascript level. (exception cannot be caught because this is client side scripting (java script))
Platform cannot send partial response when the application error occurs (for example how many records were persisted and how many were not), if the timeout happens, it just throw generic exception.
The solution is to reduce the batch size of tickets so that transaction time out error can be avoided or increase the timeout value for transaction quota to get past this error.
Thanks.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-17-2020 01:10 PM
Hi Ashutosh,
It seems like, you are looking for a bulk import. Did you try import set api ?
https://developer.servicenow.com/dev.do#!/reference/api/orlando/rest/c_ImportSetAPI
Basically, it will let you dump data to import set table and later you can use transform map to transfer data to applicable table. You can save time takes to insert data via for loop.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-17-2020 07:55 PM
Thanks for the response. I can not use import set APIs for two reasons,
1. I need to update the state of each ticket on the client whether the ticket has been successfully saved on ServiceNow app.
2. There are multiple target tables to which a ticket record is mapped to in scoped application. I am not sure whether it is possible with single transform map to transfer the data to multiple target tables.
Though there are workarounds to avoid the error for maximum execution time by reducing the payload of records sent to ServiceNow, I am looking for a standard way to handle platform errors programatically in my custom Scripted REST API so that I have better control over the error response sent to the client.
I think this is common scenario where the platform throws an exception which can be handled by custom Scripted REST API.
Thanks.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-18-2020 11:34 AM
Hi Ashutosh,
To answer your question
1- You can still achieve by updating the other tool in transform script. You can make rest api calls there
2- You can handle mutiple target tables via GlideRecord.
Since timeout happens as application level(Java), Javascript try, catch won't be able to handle.
The rough idea, :
Let's say, timeout is 300 seconds, the threshold time is 290 seocnds
at start script, create a start_time = new GlideDateTime() , on each iteration if(calculate start time - current time < threshold ) continure else break
I hope above will help you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-18-2020 07:43 PM
Thanks Rahul, this helps.