The Root Cause of Runtime Errors and Resolving the 2 Most Common Issues
The Root Cause of Runtime Errors and Resolving the 2 Most Common Issues by Adam Fothergill
If you’ve ever seen this error message after running your model in Mendix, then this post is for you.
There are many reasons for getting an error message and several message variations. In this post, I will walk you through how to find the cause of these errors, how to fix some of the more common errors, and how to minimize the potential for errors while you’re developing.
Throughout the post, I’ll also use examples. The app used for these examples has three entities: Order, OrderLine, and SaleOffer. In our app, we can add OrderLines to the Order, and we can attach a SaleOffer to the Order.
Finding the Root Cause
Once you’ve gotten an error, the first thing you’ll need to do is find out where the error occurred.
If your app is run locally:
You can simply open the Business Modeler and view the console. Within the console, you’ll find a line item in red with a red ‘X’ at the beginning. This line will provide us with the information we need.
Double click on the red line to get more details on the error message and stack trace.
There are three key pieces of information within this stack trace:
- The Microflow name and location of the Microflow error: In this example, the error is found within ‘IVK_DeleteOrderLine’ in the exclusive split (gateway) with caption ‘Number > 0?’
- The error that occurred: In this example, the error relates to java.lang.NullPointerException.
- The precise expression that failed. In this instance, the failure relates to a piece within the exclusive split that caused the null pointer exception.
If your app is run in the Cloud or from the Service Console
In this scenario, you must access the log files and look for a line that starts with ‘ERROR’ with a timestamp that matches the time of your error. All of the necessary details are displayed in order in the log.
Now that we know how to find the location of our error, let’s look at two common errors and some patterns to help avoid them.
Null Pointer Errors
The null pointer error occurs when there is no object returned from a retrieve or when an attribute on an object is empty. In my first example, the Microflow failed because we deleted an OrderLine, but checked that the number was greater than zero.
Let’s take a look:
We see the exclusive split that is causing the problem (from point (1) earlier), and since we now know the potential causes of our exception, we can begin fixing the problem.
Fixing null pointer errors – option 1:
Add a check to see if the Number attribute is empty or if the OrderLine object is empty:
These checks are not always necessary – if it is impossible for the object to be empty, then there is no reason to check if it is empty. Note that ‘true’ always leads horizontally – this is a best practice.
These checks can also be done in one exclusive split:
$OrderLine != empty
$OrderLine/Number != empty
Functionally these are the same, but the separate splits can make the Microflow easier to read and understand. Note that the order is important here; you must first perform the empty checks or the evaluation of $OrderLine/Number>0 will still cause a null pointer error.
Fixing null pointer errors – option 2:
If the retrieve of an entity is returning empty, try implementing a ‘GetCreate’ pattern. This pattern is implemented by using a Microflow action instead of a Retrieve action. This example shows what happens when we want to update the SaleOffer on the Order, but there isn’t a SaleOffer associated to the Order yet.
Use the GetCreate pattern in this instance. Instead of simply retrieving the SaleOffer, call a Microflow that is guaranteed to return a SaleOffer. The Microflow below shows how this pattern works.
The first step in the Get Create pattern is to attempt to get (retrieve) the SaleOffer. Once we have attempted this, we check if it was successful. If a SaleOffer is found, we simply return this SaleOffer. If the retrieve failed, we then create a new SaleOffer and associate it to the Order. This way the next time this Microflow is called, the retrieve will succeed. Finally, we return the NewSaleOffer.
This pattern should only be implemented when it is safe to create a new instance of the object. Depending on the situation, it may not always be appropriate to do so. In that case, you must simply perform the empty check and proceed accordingly.
Security is an important component within any domain model, Microflow, and page. If you need a refresher, you can read about security in more detail here. However, when testing with security enabled, you may get error messages with the phrase ‘failed for security reasons.’ One of the more common security errors relates to entity access.
Apply Entity Access is a setting in the properties of the Microflow. The quickest way to tell if entity access is applied is to check the background color of a Microflow. There will be a slight tint to the Microflow if entity access is applied.
In the example above, the Microflow shown on the right has entity access applied. When entity access is applied, the security set on the entity will take precedence over the Microflow access.
For the purposes of this example, assume we have two user roles, ‘User’ and ‘Administrator,’ and two module roles, ‘User’ and ‘Administrator,’ with the ‘User’ being mapped to the ‘User’ module role, and a similar construct for ‘Administrator’.
When investigating a security error, we follow the same steps as before – going to the console to find the red highlighted information which will bring us to the action that caused the error. For example, we find out our error is occurring here:
We see that this Microflow has entity access applied (by the tint of the background), so we know we must check the security of the entity and the Microflow. The Microflow is accessible by users with the user role ‘Administrator’ and the following security settings on the entity SaleOffer:
From here, the problem is identified – the ‘Administrator’ is attempting to create the SaleOffer entity in the Microflow but does not have permissions to do so. There are two ways to resolve this, but keep in mind that the proper solution will depend on the specific use case:
- Add the permission to create the SaleOffer to the ‘Administrator’ module role
- Make the Microflow not-accessible to ‘Administrators’
These are just a few examples of the runtime errors you can get. Are there others that you see often? Is there one that’s difficult or confusing? Let me know, or talk about it in the comments below! Don’t forget to check in on the Error Handling webinar, too!