Registration

Dear SAP Community Member,
In order to fully benefit from what the SAP Community has to offer, please register at:
http://scn.sap.com
Thank you,
The SAP Community team.
Skip to end of metadata
Go to start of metadata

SAP Screen Personas


 

Scripting: Error Handling and Debugging


SAP SCREEN PERSONAS KNOWLEDGE BASE - by Regina Sheynblat , Kranthi Kumar Muppala

Updated in Application Help SP08 9/20/2018

Purpose

This article describes a few options available to handle errors that occur in scripts and a few tips on how to debug scripts.

Overview

Errors can occur in scripts when an unexpected condition is met or when the script developer has made a mistake. Most error scenarios can be handled by a piece of code that detects them and perform an action or a set of actions to remedy the situation. In JavaScript and most programming languages, the concept to detect and rectify errors is called exception handling. To put it in simple terms, at the source of the error, an 'exception' object is created with necessary information and the execution of the script is interrupted. The 'exception' object can be inspected to identify the cause and rectify the situation by executing a fail-safe piece of code.

The term used by programmers to detect and resolve errors in code is called 'debugging' and there are tools to help with this task. Most modern browsers support the required tools to 'debug' JavaScript code.

Error Handling

The SAP Screen Personas scripting feature supports JavaScript exceptions and a list of known exceptions raised under error conditions is available in the API documentation available on the server at this location:

http(s)://<host>:<port>/sap/bc/personas3/core/resources/doc/PersonasScriptingAPIDoc.html

These exceptions and any other exceptions raised within the script can be caught using a try-catch block and necessary actions can be taken.

Handling Known Exceptions

In the following example, I will use the getCellValue function of the GuiGridView control to fetch the contents of a column that does not exist. From the documentation, the function raises or throws two exceptions - RowIndexOutOfRange and WrongColumnName.

getCellValue(Number rowIndex, String columnName) throws RowIndexOutOfRange, WrongColumnName

String

This function returns the value of the specified cell. This method will only return values if the row is visible or in other words the following conditions are met: firstVisibleRow <= rowIndex < min( firstVisibleRow + visibleRowCount, rowCount) . Use property firstVisibleRow to page to the right set of rows before reading their values. If the specified cell is outside of the visible row range or the column does not exist, then an exception is thrown.
Exceptions:
RowIndexOutOfRange: WrongColumnName:

If I execute the following piece of code in the details screen of SU01 transaction with the 'Parameters' tab highlighted, an error occurs because there is no column named 'XYZ' in the Grid View control.

Unhandled Exception - WrongColumnName
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpPARAM/ssubMAINAREA:SAPLSUID_MAINTENANCE:1104/cntlG_PARAMETER_CONTAINER/shellcont/shell").getCellValue(0, "XYZ");

There is no error displayed to the user. However, this statement causes the script to stop execution and there is some error information logged to the browser console that looks like below.

Exception Details Logged to the Browser Console
Error during script execution:
WrongColumnName - getCellValue(): Column with name 'XYZ' does not exist.
Error
    at new sap.personas.scripting.scriptingEngine.oProtected.Exception (http(s)://<host>:<port>/sap/bc/personas3/core/script/sap/personas/fw/its/scripting/ScriptingEngine.Common.js:89:17)
    at sap.personas.scripting.scriptingEngine.GuiGridView.getCellValue (http(s)://<host>:<port>/sap/bc/personas3/core/script/sap/pe…nas/fw/its/scripting/objects/ScriptingEngine.Objects.GuiGridView.js:255:19)
    at eval ([AppID:SU01]>[Flavor:Test_Flavor]>[Script:wnd[0]/scrptPersonas_0-TestErrorHandling]:4:137)

The error situation shown above is most likely a script developer mistake. The same behavior occurs when the the getCellValue function is used with a row index that is outside the bounds of the available rows. In this case, a RowIndexOutOfRange exception is raised by the scripting engine. The following piece of code will demonstrate how the exception can be caught and execute a fail-safe or display a prompt to the user with details of the error.

Exception Handled in a try-catch Block
try{
	session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpPARAM/ssubMAINAREA:SAPLSUID_MAINTENANCE:1104/cntlG_PARAMETER_CONTAINER/shellcont/shell").getCellValue(0, "XYZ")
} catch(oError){
	var sErrorMessage = "An error occurred while executing the script. Details: \n";
	sErrorMessage += "Error ID: " + oError.name + "\n";
	sErrorMessage += "Error Message: " + oError.message;
	session.utils.alert(sErrorMessage);
}

The exception object contains properties like the name (ID of the exception from the API documentation), message and stack (stack trace for detailed information of function stack).

Handling Other Exceptions

Similar to the exceptions mentioned in the API documentation, native JavaScript functions or functions from other libraries raise exceptions and these can be caught and rectified. Here's an example of an error that occurs when a function or property of a variable with 'undefined' or 'null' value is accessed. The error description indicates that a 'TypeError' exception occurred.

Handling Other Exceptions
try {
	var oControl;
	var nTotal = oControl.text;
} catch (oError){
	var sErrorMessage = "An error occurred while executing the script. Details: \n";
	sErrorMessage += "Error ID: " + oError.name + "\n";
	sErrorMessage += "Error Message: " + oError.message;
	session.utils.alert(sErrorMessage);
}


It is not necessary to display the error message to the user. There are instances where a user needs to correct data - like filling in a field value or fix an incorrect value. In such cases, the exception can be caught and an appropriate error message on the status bar can indicate the user to fix the data.

Handling Backend Errors

There are scenarios where a document being processed is locked by another user and a script tries to modify a field's value. Since the transaction will not allow the document to go into edit mode, there will be an error when the text of such a field is being set to another value. In the following example, I will use SU01 and go to display mode to view the details. The following script tries to set the last name field and there is a backend error popup that shows up.

A Script that Results in a Backend Error Popup
try {
	session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_PERSON_NAME-NAME_LAST").text = "Test User";	
} catch(oError){
	var sErrorMessage = "An error occurred while executing the script. Details: \n";
	sErrorMessage += "Error ID: " + oError.name + "\n";
	sErrorMessage += "Error Message: " + oError.message;
	session.utils.alert(sErrorMessage);
} 

 

The above result is in contrast to the previous examples where the error could be caught in the catch block. There are a couple of reasons for this behavior:

  1. The error does not originate from the scripting engine as the engine does not detect such errors. The backend error popup is created by the SAP GUI for HTML application as a means to indicate to the user that the request sent by the script was invalid. In this case, a read-only field cannot be modified.
  2. For optimization purposes, all write requests and actions are queued in the scripting engine and sent to the server only when something is read in the script. Since there is no property being read after setting the text property, the queue of requests are sent to the server after the script execution is completed. Since this is outside the scope of the try-catch block, this exception cannot be caught and the backend error popup is displayed.

One trick to catch the backend error without displaying it to the user is to make sure a control's property is read just before the end of a script or wherever there is a possiblilty of such errors. The following script when executed will not display the backend error, but will show the user the custom alert popup like in previous examples. The catch routine could be substituted to take other actions like going into edit mode etc.

Script that does not Display the Backend Error Popup
try {
	session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_PERSON_NAME-NAME_LAST").text = "Test User";	
	var newLastName = session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_PERSON_NAME-NAME_LAST").text;
} catch(oError){
	var sErrorMessage = "An error occurred while executing the script. Details: \n";
	sErrorMessage += "Error ID: " + oError.name + "\n";
	sErrorMessage += "Error Message: " + oError.message;
	session.utils.alert(sErrorMessage);
} 

 

The backend error popup displays information regarding the requests that are sent to the server. However, it does not show the origin of the error like the line number in the script etc. To display such information, use the URL parameter sap-clientDebug=X during troubleshooting. The same example will display the following popup with this URL parameter indicating that the error occurred on line number 23.

NOTE: The sap-clientDebug=X URL parameter should not be used in production as it has a lot of overhead in logging debug information to browser console.

Debugging

Modern browsers have several debugging tools that can help in identifying defects in JavaScript code. I will focus here on the options available in Google Chrome browser.

Breakpoints

The debugger tool in most browsers supports the feature to pause execution of JavaScript code at a specific statement and users have the option to step over each statement, step into a function, step out of the current function or just continue execution. The setting to pause execution of code at a specific statement is called a 'breakpoint'. Breakpoints can be either set in the script using the 'debugger;' statement or by clicking on the line number gutter in the 'Sources' tab with the JavaScript file open. When the following script is executed, with the developer tools window open, the browser will pause execution on line number 2.

debugger Statement in a Script
try {
	debugger;
	var nTotal = Number(session.findById("wnd[0]/usr/ctxtSUID_ST_BNAME-BNAME").text) + 1;
	console.log(nTotal);
} catch (oError){
	console.log(oError);
}

 

Setting the 'debugger;' statement in the script is the easiest way to create a breakpoint in the script. However, there are another way to do this. With the 'Sources' tab open in developer tools, hit the Ctrl+O (Cmd + O) key to bring up the list of JavaScript files currently loaded in the browser. Key in '[App' to bring up the list of SAP Screen Personas scripts that are currently loaded. The scripts are loaded when either the script editor is open or when the interested script is executed at least once.

If the breakpoint needs to be set at a specific condition, the 'debugger;' statement can be set within an if condition or the breakpoint in the line number gutter can be right-clicked and a conditional break point can be set. More information on this is available in Google Chrome's KB article referenced at the end of the article.

Browser Console Logging

The browser console is a powerful tool to debug JavaScript code, interact with objects and to try out code while the script is executing. The browser console is a panel within the developer tools and can be used whether a breakpoint is set or not. Additionally, the browser console is an object and the functions on this object can be used in scripts. The most useful function is the console.log function which can be used to print data to the console. This can be used to print values of variables that can be useful when developing scripts. Here's an example of how such a statement can be used and the corresponding output in the browser console.

Printing a Value to the Browser Console
try{
	session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpPARAM/ssubMAINAREA:SAPLSUID_MAINTENANCE:1104/cntlG_PARAMETER_CONTAINER/shellcont/shell").getCellValue(0, "XYZ")
} catch(oError){
	console.log(oError)
} 


Alternatively, the session.utils.log function can be used so the script can be used across GUIs. Here's an example.

Print a Value to the Logging Panel
try{
	session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpPARAM/ssubMAINAREA:SAPLSUID_MAINTENANCE:1104/cntlG_PARAMETER_CONTAINER/shellcont/shell").getCellValue(0, "XYZ")
} catch(oError){
	var sErrorMessage = "An error occurred while executing the script. Details: \n";
	sErrorMessage += "Error ID: " + oError.name + "\n";
	sErrorMessage += "Error Message: " + oError.message;
	session.utils.log(sErrorMessage);
}

More information on the browser console can be found in Google's KB article referenced at the end of the article.

Debugging OnLoad and OnAfterRefresh Scripts

The scripts assigned to OnLoad and OnAfterRefresh screen events can be tricky to debug in scenarios where a particular screen is skipped or a switch to another flavor or transaction occurs. In such cases, the URL parameter suppressOnLoadEvents=X can be used to deactivate execution of such scripts. The script editor can then be opened to debug or modify the scripts.

Related Content

Related Search Terms:

SAP Screen Personas, Scripting, Debugging, Error Handling, Developer Tools

Related SAP Notes/KBAs

Google Chrome - How to set breakpoints

Google Chrome - Using the console