You may love C/AL as a language, but there is an area in it that you must just hate. It’s the error handling. Plainly put, and being actually quite positive about it, in NAV, error handling just sucks. If an error happens, it happens. You have only one possibility to actually capture the error, and it’s the IF CODEUNIT.RUN construct, and it’s limited because you can do it only once per transaction, and if you want to do it twice, you must COMMIT your transaction first.
But still, capturing an error is one thing; actually handling it is quite a different thing altogether.
Handling an error means taking necessary steps to continue execution after an expected error occurs. And these steps can easily depend on the context of the error. There is quite a difference between a division by zero, and a TESTFIELD failure.
Take a look at this useless code:
It does nothing but fails in six completely different ways, depending on the actual processor mood. They are, in order of appearance:
When you call this codeunit with the IF CODEUNIT.RUN construct, you will capture the error, but handling it may become tricky. In versions earlier than 2013, you could only check the GETLASTERRORTEXT function to see if you can parse out some text out of it in a smart way, but it was usually an exercise in futility, because of possible multi-language environments – it always gives you the error message in the end-user language. In 2013 we’ve got the GETLASTERRORCODE which was language-independent, and it always used the same code for the same exception type, making error handling simpler. However, it still had shortcomings.
In NAV 2015, we get a new error handling function: GETLASTERROROBJECT, and I just love its signature:
It returns a DotNet, and if you don’t immediately know which one it is, let me tell you – it’s the System.Exception type.
Now we are talking business.
The difference is substantial. Even though in NAV 2013 you could use the GETLASTERRORCODE to get a (fairly) unique error code for each different type of error, receiving the actual exception object gives at least these two important benefits:
- Exception is strongly typed, and you are absolutely guaranteed to be able to uniquely identify the kind of exception from the type of the exception object you receive. GETLASTERRORCODE still only gives text, and since different assemblies could easily declare types with the same names, you could theoretically get two different exceptions with the same ID. With the exception object, there is no such fear.
- Exception object actually gives you insight into the exception context. Depending on the type, you can access relevant properties (or methods) on the exception object to see anything you want to know about why the error occurred.
In any case, exception handling is an important topic, and I see it has been for better part completely ignored by NAV bloggers. That’s why I have decided to release a series of blog posts about handling exceptions in NAV 2015 (some of it will apply to earlier versions). I hope you find it useful.
We are getting closer 🙂 and I’m glad to see the ongoing dotnet integration of C/AL hoping to see more of this in the upcoming versions.
Yes, we are – but there will either be a serious redesign on how .NET integrates into C/AL, or something else (which I can’t see) because this error handling thing has revealed to me some shortcomings that I hope to get time to blog about. Serious shortcomings, that is.
Great idea about the series of blogs on error handling 🙂
Thanks! 🙂
Pingback: Better error handling in NAV 2015 – 10/13, Navigate Into Success |