Yesterday I was going through various Dynamics NAV blogs and found a very interesting article about error handling. Over past few weeks I was planing to write a article about error handling and however it always got delayed due other topics came up with Microsoft Dynamics NAV 2015.
After reading the article of VJEKO, I thought to write another article based on his findings.
Been in the year 2015 with a new product, with very exciting new functionality and very advance technology, how many of you wondered why Microsoft never introduced error handling to Microsoft Dynamics NAV programming (C/AL Editor).
Certainly I did! I always wondered why Microsoft is so late to introduce error handling into C/AL programming. Then I thought will they ever going to introduce error handling to C/AL programming.
Now I have my answers. Microsoft, introducing error handling to C/AL programming is very close to zero (0), as they have their reasons and they always justify it.
However very small part of me think otherwise.
With this .NET interoperability and new .NET related introductions to NAV, I feel that Microsoft slowly bringing .NET programming to picture and I feel ONE DAY they will remove C/AL programming and will bring all their products to a one programming platform. (I do have very little info about this and this is my personal idea).
Lets keep it behind for a moment and move to our main topic of error handling.
Why Microsoft is not going to introduce error handling to Microsoft Dynamics NAV programming ?
Answer to this question is relaying on Database and Transactions.
In Microsoft Dynamics NAV, we do not have any control over Transactions. Transaction implicitly start when the first database write statement executed and it automatically commits with the code execution completes. Only control we have is to call the COMMIT function to commit the transaction by force.
That also somewhat OK because we still have little bit of control over that. But can we ROLLBACK a commit transaction? No! ROLLBACK implicitly happen when ever there is any kind of error during the transaction.
I will take the same example VJEKO, has taken to explain the above statement.
I have created my own codeunit and within that I did not wrote any code line ( Blank codeunit) and saved it as “Codeunit to run”.
Then as the second code unit I have created a codeunit called “My Codeunit” and then wrote following lines in that.
What I am trying to do in here is inserting a new customer and then run my empty code unit. Compile and run this codeunit.
|
Codeunit 5001 |
Without any error this get executed and this was what we expected.
After that I went back to “Codeunit to run” and wrote a Error statement in the OnRun trigger and saved it (Intention is to generate an error while next execution).
Then I came back and ran “My Codeunit”. This time it get executed and once the error occurred from the codeunit it will automatically rollback my newly created customer and throw my error message. So far it is perfect and we knew this would happen because this was Dynamics NAV simple behavior.
So then what is the problem?
What if we rearrange our code like below in the “My Codeunit”. It get compiled without any error. With this arrangement of code we can handle our error. How ?
If codeunit throw any error, we can write a else statement and execute completely different code segment.
Having that in my mind I ran my codeunit and here it goes!!
I got following error, Very long and very detailed error.
The following C/AL functions are limited during write transactions because one or more tables will be locked. Codeunit.Run is allowed in write transactions only if the return value is not used.
What it basically means is that we cannot use the return value of the code unit.
Why is that? If you check the code lines, as soon as the first line get executed, Transaction get started implicitly because first line is a write transaction. In the very next line, codeunit throws an error. In this line we have written and restructured our code to execute and continues even IF the codeunit execution fails.
That is where the problem is.
Normally what happen in NAV is if there is ANY error during a transaction Dynamics NAV automatically roll back all the changes happened during that transaction (Simple and easy).
So if we execute this code segment what will happen to the database changes occurred during our code execution? and which database changes should rolled back? Only those happen inside of the codeunit or all the changes happened before entering into codeunit.
To make it simple for everyone Dynamics NAV asked you to restructure your code to avoid this kind of complexity and avoid you to use returns values of a write statement.
If we have TRY {} Catch in our coding imagine the frustration we all will have to go through. As a example if we have 5 successful transaction line and in the next line it failed and what we should do? Should we allow to commit above 5 transactions or should we rollback all those 5 transactions?
As VJEKO, rightly mentioned in his blog, try catch is easy if we have no transactions. Once the transaction enters to the arena you will end up in a real mess of deciding which should commit and which should not commit.
As VJEKO, mentioned there are solution to that by controlling transactions directly and introducing savepoints to Dynamics NAV programming. You could explicitly make it commit through the use of savepoints, and then explicitly rollback to the last successful savepoint. To do this NAV has to include savepoints after each line of code and then keep track which savepoint should use if transaction get failed. By doing this and adding implicit transaction to NAV will break the simple and yet very advance foundation. If Microsoft really do that then I will lose one thing that I really love about in C/AL programming, that is Handling transactions by its own. Therefore lets get satisfied with what we have right now and lets not ask for error handling in C/AL programming.
Once again thank you VJEKO for your lovely article and if any of you need more info please refer his blog post.
Thank you and Regards,Tharanga Chandrasekara