Sometimes it is inelegant, inconvenient, or even impossible to correctly handle an exception within the method (let's call it methodA) where the exception arises. In those cases, it is better to add a "throws" declaration to *methodA, and then whatever method calls methodA(...) will need to consider whether it can handle the error (with a
try... catch ... block), or whether it too is not well-situated to handle the error.
For example, somewhere in your data model, you might have a method called loadFromFile() that loads a GameBoard (or TerrainMap) object from a file. However, a FileNotFoundException (or other *IOException might occur when you attempt to read from the file.
Can we handle this exception properly within loadFromFile()? No!
This method could be getting called from within an action handling method for a JavaFX MenuItem, in which case, the appropriate response might be to display an Alert popup window to the user, and then perhaps ask them to select a file again. On the other hand, loadFromFile() could also be happening from a different console/command-line/terminal application whose job it is to open all .gameboard files in a folder and convert them each to .obj format. In this case, the error should be displayed to the console, and the user should be asked how to respond using a Scanner that's reading from System.in.
loadFromFile(...) has no way to know the broader context of how it is being used, so it should just add the throws IOException declaration to it's method header, and announce to the world that anyone who calls this method should be ready to handle the possibility of an IOException.