Error|Exception handling in AnyLogic models

Updated: Jun 8


This is a special guest blog post by Yash Mishra giving a quick overview of how you can manage errors inside an AnyLogic simulation model. He shows an example of standard error handling architecture available inside Java and gives an example of how you can practically use it inside AnyLogic with a GIS map in trying to find a route. He also shows how you can throw your own errors in the code to create a more robust model that warns you when things are not going as expected.


Note: This post is just a quick overview of error handling. Watch this space for when we will be releasing the Advanced Java for AnyLogic course later this year, which will cover this, and many other topics in more detail. If you are still a beginner, you can use our Java for AnyLogic course to get you started.


gif

While building a simulation model, we often encounter errors. Sometimes they occur when compiling the model, compilation errors, and sometimes during model execution, runtime errors. When these errors occur, we look into the console for error details and work on correcting them. This post is going to focus on how you can handle runtime errors.


Technical note: Errors and Exceptions are two different classes in Java but more on this in the Advanced Java for AnyLogic course. In this post, we will be using errors and exceptions interchangeably for simplicity's sake.


Runtime errors can occur due to various reasons, but when they occur, your model execution will stop immediately. There are some runtime errors like OutOfMemoryError, VirtualMachineError, etc., which are not recoverable. Still, there are many runtime errors that can be handled, like dividingByZero, indexOutOfBounds etc., as well as the famous NullPointerException. Sometimes we don't want the model to fail when these errors occur but rather catch them, handle them and control the following steps once the error occurs.


All such errors can be handled through a powerful mechanism known as exception handling. In Java, it is done through try-and-catch blocks.


try {
       //Do some actions that might cause an error, e.g. divide by zero
} catch(Exception e) {
       //print cannot divide by zero
}


Just by placing the code that might throw an error inside a try-and-catch block, the model will be able to handle the error itself and avoid the model execution being stopped abruptly.


Some functions in Java will force you to apply error handling. Try typing in the code below and see the compilation error you get. See if you can resolve it using a try-catch method and let us know in the comments if you succeeded ;-)


SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
Date myDate = dateFormatter.parse("2021-02-01");

Real-world use case in AnyLogic

Let us dive deeper into the concept and see a real-world implementation of exception handling. Recently I was building a model for an e-commerce company, and within the shipping department, there was a requirement to find the best route for delivering an order. The preference for delivering an order was using a rail route, if available, and if not, then road.


To start the model, I use the map object available in the Space Markup palette.


Since the preferred route is by rail, we selected the Road type to "Rail" on the map object parameters


In order to determine the best route, we needed to get the distance between two locations. On the map, we can calculate the distance between a source and destination address and get a route by using the getDistanceByRoute functionality provided with the map object.

map.getDistanceByRoute(latFrom, lonFrom, latTo, lonTo)


For a simple demo, I would create a button control and apply the function stated above in the on-click section in the button control to find a distance. I will use New York as the source (40.71, 74.00) and Washington D.C. as the destination (38.90, 77.03).



We can see that it returns the distance by rail as per the rail route. That’s awesome. Isn’t it?


Now let’s look at another example where our source is somewhere in the outskirts of Baltimore (39.76, -77.51) and the destination is a remote location near Toronto (43.95, -81.27).



It is showing me a straight line... that doesn’t look like a rail route. Something is not right....


So, when I took a closer look at the map properties, I found that I need to select show error dialog if the rail route doesn’t exist.


However, if I select the show error dialog it will produce an error when no rail route exists which will not solve my problem because when an error is thrown, my model will stop abruptly. While we actually want to find an alternative route by road...


So along with the show error dialog, I need something which handles the error produced by the map object when there is no rail route available. To overcome this we will use the error handling methodology using try-and-catch blocks.


So, in my button control on-click section, I wrote the following code to handle the error and safeguard the model from stopping abruptly.


try {
       message = "The Rail distance is: " + 
       format(map.getDistanceByRoute(39.76, -77.51, 43.95, 
       -81.27)/1000) + "KM";
} catch(Error | Exception e) {
       message = "couldn't find the route by rail, will deliver by road";
}

P.S. the code "Error | Exception" simply means "...catch either Errors or Exceptions". You can add as many throwable class types you want to catch and simply separate them with a "|"


Thanks to error handling, we can keep the model running, but the business needs to deliver the products by road if there is no rail route available. For all practical purposes, a map object in AnyLogic can produce a route either by rail or road but not by both.



So, the first solution that comes to mind is adding another map object and calculating the distance by road from it, in case the first map object throws an error due to the unavailability of the rail route we will then ask the second map object....

Overcoming another roadblock

Adding two map objects on the same agent is not allowed in AnyLogic.


gif

To overcome this, AnyLogic provides a Route Provider object which would use the map object to find the distances.

<