This is an intro post to the Error Message Mgt. codeunit and related objects. NAV has never brilliant when it comes to error handling, for a couple of reasons.
- The error messages themselves sometimes leave a lot to be desired
- The whac-a-mole nature of fixing multiple errors by finding one at a time and attempting to post/register again
There isn’t a lot we can do about the standard error messages, but we can write more considerate errors for our users. Describe the problem and guide the user to the solution as much as possible i.e. not “There was nothing to handle”.
What about #2? What if we could line up all the moles so that the user could whack them all in one go?1 We can use the Error Message Management objects to do just that.
This is a useful post you could take a look at – http://www.mynavblog.com/2019/04/09/how-to-write-error-and-confirm/ – but even having read that I still struggled my way through how to use it and write tests around it. I didn’t find the framework particularly easy or intuitive to work with so hope I can save someone else some head-scratching.
1 metaphorical moles. I’m not endorsing whacking actual moles.
You might want to use this framework when you’ve got some process that could throw errors for multiple different reasons. Usually these are going to be some posting or registering routine for a journal line or a document.
Often there are all sorts of things that can wrong with those routines – posting date ranges, dimension errors, mandatory fields that have not been populated, missing posting setup, missing no. series… blah blah blah.
Rather than just throwing an error for the first problem we encounter we want to collect them together so that the user can fix them before posting again.
I was going to attempt a single overview post, but I’ve decided against that. I think it will be more useful (hopefully) to work through an example – albeit a silly one – in stages. I’ve got a small app for posting a record of video calls – because that’s what we need right now, more video calls and more admin.
The app adds a journal page to record the platform (Teams, Zoom, WhatsApp or Skype) the type of call, date, duration and participants. Before the journal can be posted there is a deliberately convoluted process to check for various errors. Concisely summarised below:
- No. of Participants must not be 0
- Duration (mins) must not be 0
- Posting Date must not be blank
- Posting Date must be within allowed posting dates for the user
- Zoom calls cannot be over 40 minutes when the No. of Participants is > 2 – I’m a cheapskate and have got a free account
- Teams cannot be used for a call type of Family Quiz – surely no family is that corporate?
- WhatsApp should not be used for groups of more than 4 – it’s bad enough with 2
- WhatsApp should not be used for a call type of Customer Demo – I mean, you don’t…do you?
- Skype isn’t used for more than 2 participants – I know technically it can be…it just isn’t
- Family quizzes can’t be held Monday – Thursday
- A call type of Daily Team Call cannot be more than 45 minutes long – you need to find a smaller team to have daily calls with
- A call type of Daily Team Call cannot have more than 30 participants – see #11
While this is daft, it is an example of how a journal might not be able to be posted for lots of different reasons. Normally we expect the user to fix those errors one at a time and, if they’ve still got the will to live, post the batch when they have resolved them all.
At the moment I’m just using Testfield and Error to throw errors when a journal line is valid. Over the next few posts I’m going to see if I can the Error Message Mgt objects to build a list of errors and display them all at once. Then we’re going to talk about how to test this behaviour.
The source code is here: https://github.com/jimmymcp/error-message-mgt Disclaimer: it sucks. This is an example of using the error handling tools, not of how to write a good journal.
Sales Header Posting
In the meantime, if you want to see an example of this sort of error collection in the base application then look at SendToPosting on the Sales Header table.
ErrorMessageMgt.Activate(ErrorMessageHandler); ErrorMessageMgt.PushContext(ErrorContextElement, RecordId, 0, ''); IsSuccess := CODEUNIT.Run(PostingCodeunitID, Rec); if not IsSuccess then ErrorMessageHandler.ShowErrors;
Then in the Sales-Post codeunit you’ll see this kind of thing (this from CheckAndUpdate)
ErrorMessageMgt.PushContext(ErrorContextElement, RecordId, 0, CheckSalesHeaderMsg); CheckMandatoryHeaderFields(SalesHeader); if GenJnlCheckLine.IsDateNotAllowed("Posting Date", SetupRecID) then ErrorMessageMgt.LogContextFieldError(...);