Skip to main content

Debugging Technics in X++ (AX)


Interrupting the code execution :

When you have written some code that is causing an endless loop (or a very long execution) and you want to know what

code is currently keeping the client busy. The easiest way is pressing [Ctrl] + [Break] on the keyboard.

This will stop the code execution and show up a message box: Are you sure that you want to cancel this operation?

If you hold down the [Shift] button on the keyboard while you click at the No button of the message box, the AX
Debugger will be launched exactly at the line of code that was about to be executed. From here you can continue
to step over / into line by line and try to identify the cause of your endless loop.

If breakpoint is sometimes not hit?

Sometimes it happens that a breakpoint is not hit although you are sure the respective code was executed

 instead of putting a breakpoint at a line of code insert the breakpoint keyword.

public void executeQuery()
{
breakpoint;
super();
}

How can I get the current X++ call stack?

The static method xppCallStack() of the xSession Kernel class returns the current X++ call stack://...

Info(con2str( xSession::xppCallStack() ));
//...

How can I see the call stack that resulted in X++ exception?

When you run into an exception that is showing up in the InfoLog usually double clicking at the error brings you to
the line of code where the error was raised.Sometimes knowing the line of code where the error was raised is however
not good enough as the individual call stack is what you need to know. Putting a breakpoint at the line of code where
the exception was raised is helpful, what however if you are in a loop and you don't know what loop iteration results in
 the error especially if the error is random?Instead of putting the breakpoint at the line of code where the exception
might be raised, put a breakpoint in the addmethod of the Info class,
e.g. at the line switch (logLevel).

Exception add(
// ...
;
switch (logLevel)

// ...

Info::add is always called when something is written to the InfoLog and since an exception shows up in the InfoLog as soon
as the exception was raised the Info::add method is called and here you will hit your exception

Comments

Popular posts from this blog

Form Auto refresh in D365 fo

Here I will explain one of the requirements I came across to refresh from automatically without User interaction.  Note: Make sure we do have all the handlers to stop UIrefreshing after certain hours of execution, else it causes the system to slow down after a certain time of continuous usage of this UI in the below example to overcome this case we use to check session login time and stopping form to refresh after certain hours of execution. Recommended to use this on pages that hold less data or smaller data sets. - NoofSeconds .value() is an integer control on UI that allows the user to choose a value.( best to fix a value like 5 seconds or a Minimum value to avoid unnecessary executions) Create a new form method and create as of below. void refreshFormWithTimeout (AsyncTaskResult _result)     {         System.Exception ex;         try         {              if(!element.closed...

Splitting Sring through X++ in DAX

  Splits a string into a list of substrings delimited by elements in the specified delimiter string. static void StringSplit(Args _args) {        List            list = new List(Types::String);     container PackedList;     ListIterator  iterator;     str can = "Lev_Sales00001_1";         list = Global::strSplit(can,"_");     iterator = new ListIterator(list);     while(iterator.more())     {       PackedList +=   iterator.value();         iterator.next();     }     info(conPeek(PackedList,1));         } output :  

SQL script to Fetching Tables list holding more data

  There may be times when we need to restore a database from a non-production or production environment for troubleshooting purposes, and we may encounter a DB size issue or need to know a list of tables with large amounts of data in order to enable purging them. This query returns a list of tables that contain large amounts of data in sequential order.  Query to Execute in SQL SELECT s.Name AS SchemaName             ,t.Name AS TableName             ,p.rows AS RowCounts             ,CAST(ROUND((SUM(a.used_pages) / 128.00), 2) AS NUMERIC(36, 2)) AS Used_MB             ,CAST(ROUND((SUM(a.total_pages) - SUM(a.used_pages)) / 128.00, 2) AS NUMERIC(36, 2)) AS Unused_MB             ,CAST(ROUND((SUM(a.total_pages) ...