How to write ERROR and CONFIRM?
For many years when you needed to write any confirm message or an error message in a code there was nothing complicated. However in Business Central there were introduced new functions for both of those messages. One was already there for some time but the error handler is brand new thing which is added in Spring Release 2019.
Confirm Management
Writing simple CONFIRM was very easy so I will not go into details with that. However did you always add before If GuiAllowed() then ? I bet not all of you remember about that.
As I see Microsoft has been changing CONFIRM messages recently in the system and instead of that, uses special function. Therefore there is a new codeunit Confirm Management which contains only two functions ConfirmProcess and ConfirmProcessUI.
And if you would look into the standard code there are many places where that functions are already used – I found over 340 (mostly in Codeunits).
First one, ConfirmProcess, you should use if you want to return the default value in case that the gui is not allowed. Second one you should use if you always want to return False in case that the gui is not allowed.
Here is example of standard code which uses the function from that codeunit.
ERROR handling in the posting codeunits
I should start that writing an error message in most cases stays as it was. However there is quite a big change if we want to handle error during posting. I will give you an example with not allowed posting dates. Till now (here is code from cumulative update 3 for previous on-prem release) there was only FieldError.
Users see a normal error message when posting document with the posting date which is not in an allowed range.
In the newest release the same message looks totally different. You will see a list of all errors when you will try to post the sales order (or other document). This will give an user possibility to fix all issues before trying one more time.
How does it work? First of all there had been added two new Codeunits – Error Message Handler and Error Message Management. Also there had been added new table which stores temporary records for the error messages – Error Message.
There is also a change in function SendToPost which now allows to catch all errors which will occur during posting of document. As you see at the end of the function – if errors exists then they are shown.
To catch and store an error there is used a function in Codeunit Error Message Management – LogContextFieldError. Example how to use it you can see below.
ERROR handling example
To show you how you can use it I prepared small and very useful functionality. I added a field in the Sales Header called Always True and decided that if the field is false I should block posting. So here is a field.
Next I added a new subscriber to the event OnAfterCheckSalesDoc which you can find at the end of the function CheckAndUpdate in the codeunit Sales-Post. As you can see I did not add a simply Error() but I used function LogContextFieldError.
So now user, until mark the field Always True, will see, not only error related to allowed posting dates, but also my new message. And since I added a RecordId to Sales Header after clicking an action Open Related Record user will see my Sales Order.
I must say that I really like the idea to show all errors at the same time. It can save user a lot of time and will allow to fix all in the same run of posting.
Thank you for the post. But I have some remarks. Concerning mentioned function SendToPost: Are “SendToPost” and “SendToPosting” the same? Nad ID objects are missing in your post (that is a pity). Can you add them? I think you mean table 38, codeunit 90. And declaration of some variables are missing as well (e.g. ErrorMessageHandler in function SendToPosting). If a reader hasn’t installed propper version he can’t investigate source code.
REMARK: If a reader doesn’t stop reading he can find object name almost in the end of post. (codeunit 90). But the reader needs to know object much earlier.
But once again, thank you Krzysztof very much.
In principle I like the concept, but the concept have some flaws.
I have done Developer Training for years, and always pointed out Why it is important to use “GUIallowed” check, as well as having the concept of “Default Value”, so things can run smoothly in Job Queue as well as when a user is executing directly.
One thing I always added to this concept were the ability to “run silent” for a user, so a “HideValidationDialog” around it.
If we take the ConfirmProcess function it would then become:
[External] ConfirmProcess(ConfirmQuestion: Text; DefaultButton: Boolean; HideValidation: Boolean): Boolean
If (Not GUIallowed) or (HideValidation) Then
Exit(DefaultButton);
Exit(Confirm(ConfirmQuestion,DefaultButton));
Having this option will give us a much needed flexibility in calling into standard code; instead of having to “re-code” many things, so we end-up with duplicated code instead.