(SM) Support Tip: Troubleshoot JavaScript code

The JavaScript code in ServiceManager is not easy to debug. There is a trace parameter debugjavascript, but the output is often not what is required.

 

A frequently used method is to place debug statements into the JavaScript code that will print a message to the messages pane in the client respective to the log file. The message may only indicate a location in the code was reached, or output the contents of a variable.

 

Print to the message pane:

 

print("message");

 

Print to log file:

 

 var rc; var success=system.functions.rtecall("log",rc,"message");

 

As this statement is quite complex, you might want to implement a function log(message).

 

In order to easy localize debug messages later, it is best practice to reference the code location in the message.

I.e.:

 print("SL WSCentralServiceService.1: message");

 

 

An advanced debugging method is to retrieve the current call stack: While we know the current location, we might not know from which function this function was called, as well as the argument list.

 

The call stack is available in the JavaScript Exception object. For that reason, we can cause an error, and handle the exception raised to retrieve the call stack.

 

Error()@:0

Stack()@'teststack':1

logStack("abc")@'teststack':32

@'teststack':37

 

In the catch-block of an try { .. } catch(ex) { .. } statement use ex.stack to retrieve the call stack of the error location if there was an error while processing the try-block.

 

Each line has this format:

function(list of parameter values)@’ScriptLibrary’:line number

 

This function will return the call stack:

function Stack() { try { throw Error() } catch(ex) { return ex.stack } }

 

You may print it either to message pane or log file.

 

Note: This function returns the current call stack at the location where you called it – this is not the location of a runtime error.

 

For JavaScript implementations that implement a logger object, this function can be used to enhance the output of the messages logged.

 

For example, the ServiceManager Integration Suite implements a logger in ScriptLibrary smis_logger.

So we place our Stack() function at the bottom of this ScriptLibrary and call it form a method of the logger object.

 

I.e.:

Replace in the error() method

FROM:

error: function(context, msg) {

    this.log("ERROR", context, msg);

TO:

error: function(context, msg) {

    this.log("ERROR", context, msg "\n" Stack());

 

This means, whenever an error message will be logged using an instance of the logger object, the JavaScript call stack will be printed as well.

 

Note: When printing to log file the line breaks will be removed: So the output will not be formatted nicely, but still contains useful information.