When programming an application, you may need to know where you are in your code, especially when one method calls other methods, which may then call other methods. That’s why it’s very helpful to see the chain of methods, or the call chain, during the debugging process. For this, 4D v17 R6 provides the new Get call chain command to give you an insight into the executed code. Now you won’t have to worry about getting lost anymore!
The command returns a collection of objects. Each object represents an execution step described by its database, method type, method name, and call line. It can be used in all code execution contexts, in both interpreted and compiled mode.
EXAMPLE
Thus, finding the source of an error becomes very easy. See the following call chain with ON ERR CALL:
C_OBJECT($error;$file)
C_COLLECTION($_callChain)
$_callChain:=Get call chain
$error:=New object
$error.timestamp:=Timestamp
$error.method:=Error method
$error.error:=Error
$error.line:=Error line
$error.deep:=$_callChain.length
$error.callChain:=$_callChain
// Store the error in a file located in the database logs folder
$file:=Folder(fk logs folder).file("error_"+Generate UUID+".json")
$file.setText(JSON Stringify($error))
And here are some results:
[{ "timestamp": "2019-05-21T21:54:16.748Z", "method": "openDocument", "error": -43, "line": 3, "deep": 5, "callChain": [{ "type": "projectMethod", "name": "onError", "line": 3, "database": "Host_Database" }, { "type": "projectMethod", "name": "openDocument", "line": 3, "database": "Host_Database" }, { "type": "projectMethod", "name": "executeHostMethod", "line": 2, "database": "Component_Database" }, { "type": "formObjectMethod", "name": "detailForm.openButton", "line": 1, "database": "Host_Database" }, { "type": "projectMethod", "name": "showDetailForm", "line": 7, "database": "Host_Database" }] }]
Ok. So how can we read this? It’s pretty straightforward:
- The log has been written at the third line of the host database onError method,
- It was called by the third line of the host database openDocument method ,
- Which was called by the second line of the component database executeHostMethod method,
- Which was called by the first line of the host database detailForm.openButton form object method,
- Which was called by the third line of the host database showDetailForm method.
USE CASES
There are different uses cases for this command, here are just a few:
- Error checking – You probably already use “on error” methods that include an error log system. Prior to 4D v17 R6, you could only retrieve the error code, the error method, and the line generating the error. If the method is called from several places in your code, it could be pretty difficult to understand the context that generated the error. Now you can retrieve the entire call chain!
- Analyzing – A method is called from several other methods and you want to know where it’s called the most often, in a production environment. You can now log the method call chain and analyze the results later, without writing dozens of lines of code. To avoid slowing down performance, simply don’t use the command in all of your methods!
- NOT FOR CONDITIONAL DEVELOPMENT – Keep in mind that this feature is for debugging and/or optimization purposes. It’s NOT for conditional development based on caller methods.
RANGE CHECKING
Get call chain can be run in both interpreted and compiled mode. The command requires extra information produced by the 4D Compiler when range checking is turned on. Since disabling this option could be dangerous (resulting in crashes), we’ve removed it from the database settings. This way, it’s always activated.
However, you can still use the corresponding comments in your approved and robust code:
- //%R- to deactivate range checking from the line
- //%R+ to activate range checking from the line