Dynamics 365 Business Central and TryFunctions: be careful!

I think that most of you know what Try methods are in the Dynamics Business Central (and Dynamics NAV too) world. Try methods in AL enable you to handle errors that occur in the application during code execution. You can declare a Try method by using the TryFunction attribute as follows:

[TryFunction]
procedure MyTryFunction()

The official documentation about TryFunctions says the following: because changes made to the database by a try method aren’t rolled back, you shouldn’t include database write transactions within a try method. By default, the Business Central Server configuration prevents you from doing this. If a try method contains a database write transaction, a runtime error occurs.

Generally speaking, you don’t need to perform write transactions inside a TryFunction (for transaction consistency) and normally in the past you will receive an error if you do that. More precisely, for Dynamics 365 Business Central on-premise and for Dynamics NAV (at least from version 2017) there’s a parameter in CustomSettings.config file called DisableWriteInsideTryFunctions that is defaulted to TRUE and prevent to do writes in a TryFunction. This parameter is defaulted to TRUE also on Docker-based environments:

<!--
    Specifies whether to raise an error when AL code that is executed in the scope of a TryFunction writes to the database.
    It is recommended to update the AL code to avoid writing to the database from a TryFunction. However, in cases where this is not possible, setting this value to false allows TryFunctions to write to the database, and behave as they did in Dynamics NAV 2016.
  -->
  <add key="DisableWriteInsideTryFunctions" value="true"/>

But what about Dynamics 365 Business Central SaaS?

Let’s try to execute this piece of code in a SaaS environment:

This should raise an error… but:

As you can see, there’s no error thrown. My code executes successfully and the write transaction is performed.

But let’s do another example, more dangerous I think… Let’s consider the following code:

Here I execute a write transaction inside the TryFunction, then we raise an error.

The above code is called with the follwoing action in the Customer List page:

What happens in this case?

The write transaction in the TryFunction is executed, the error is trapped by the TryFunction and it’s returned to the caller. Result:

My Customer record is modified, despite the error. This is why you should avoid write transactions inside a TryFunction.

But now the real question: Why this is possible on SaaS?

Because as confirmed by Microsoft, writes in TryFunctions have always been allowed in SaaS since Project Madeira (practically ever). On SaaS, the DisableWriteInsideTryFunctions parameter is defaulted to FALSE and so you can perform writes. And this is absolutely not good!

This inconsistency of behaviour between on-premise and SaaS can cause serious problems if TryFunctions are not correctly used. I hope (and this is the reason I’m writing this post) that the server team will reconsider this behaviour and activate the DisableWriteInsideTryFunctions = TRUE in SaaS too as soon as possible.

It should be set to TRUE in a next minor release in my opinion (I cannot see destroying changes but only better things), but if it’s not possible, please add a Feature Management or something similar.

In the meanwhile (I’m sure that they will listen) please remember to avoid doing write transactions in a TryFunction on SaaS. Please remember that at the moment there’s nothing that checks or enforce this at source, so instruct your developers properly.

I suggest to the Microsoft BC Server team to also consider (if possible) logging telemetries for TryFunctions usage (for example, writes performed from a TryFunction). This could be helpful for troubleshooting problems.

1 Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.