One of the new features of X++ when becoming a language that only compiles to the Common Intermediate Language was the finally block. As an X++ developer, you expect the finally block to always run after a try block, regardless if an exception was thrown or not. Unfortunately, due to the complex relationship between the X++ code and the AOS, this doesn't always seem to be the case.

 

In Platform Update 24, one such problem has been addressed. Consider this code:

try

{

   Box::yesNo("Please close the browser window!");

   myTable.Message = 'Dialog was closed by user.';

   myTable.insert();

}

finally

{

   myTable.Message = 'The X++ finally block was able to insert a record.';

   myTable.insert();

}

 

The X++ developer’s intent is to always get at least one record inserted in the database - assuming, of course, that no critical errors occur, like losing connectivity to the SQL database.

 

What actually happens when the dialog box is displayed is that the X++ code waits for user interaction. If the user closes the browser window when prompted, their session in the AOS will be marked as “aborted”. The X++ code will then be resumed, but immediately hits an X++ BreakException when calling into the kernel to get the result from the dialog. The BreakException is thrown because we don’t allow calls into the kernel for a session that has been aborted. This means that the execution will jump to the finally block. In the finally block, we try to insert a record into the database. This again requires a call into the kernel, which results in another BreakException being thrown, this time terminating the finally block without inserting any record.

 

In Platform Update 24 we have improved the way that kernel calls are made from the finally block, bypassing the check if a session is aborted. This change affects both the kernel (AOS) and the X++ compiler, meaning that your X++ code needs to be recompiled with a compiler from PU24 or later to get the new behavior. An updated kernel without recompiled X++ code will behave the same way as before.

 

NOTE: your X++ code needs to be recompiled with a compiler from PU24 or later to get the new behavior

 

The kernel code that throws an X++ BreakException if the session is aborted has been updated to avoid doing this if a finally block is currently being executed. This allows the code in the example above to work the way that the X++ developer expected.

 

Note : This doesn’t prevent the X++ code from throwing exceptions while in the finally block. Any code that might throw exceptions still can, in which case execution will still break out of the finally block, unless you add additional exception handling inside of the finally block.

 

It is a good practice to keep code in the finally block as short and simple as possible - it is not a good idea to execute complex business logic there.