Users are demanding of the software they use. It needs to be reliable and assist them to complete their tasks every single time in a user friendly manner. A user may accept a well written error message when they understand the cause cannot be attributed to your application, but it is important to have a good exception handling strategy when you setup the infrastructure for your project. Here are some good practices that we found are useful to develop your exception handling strategy:
Although this post is about best practices for handling exceptions, the best way to deal with them is to avoid exceptions using basic logic. If an exception needs to be thrown because the username already exists – make sure to provide a public method that can help the client code check for it. This will provide clearer client code that will not interrupt the thought process of the developer reading that code.
Exceptions thrown at database level are not necessarily interesting to your domain layer. In fact your domain layer should not even know how the data is stored. Having a SQLException propagate to your upper layers is therefore breaking the rules, and this could cause hard coupling with your database strategy. If ever you need to switch to a NoSql database, the top layers of the code will break. Therefore it is recommended to convert your exceptions to a more generic exception. Perhaps the business logic wants to retry the action, or if this is not possible you need to notify the UI. You can categorize converted exception in checked or unchecked exceptions. Unchecked exceptions are generally caused by programming problems like a divide by zero. Checked exceptions are exceptions that your system can reasonably recover from.
Let exceptions propagate
Code nests, whether this is in hard to maintain case statements, or in a clean object structure. It is still nesting. Because the logic often happens on top – you cannot always deal with the exception on a deeply nested method. Make sure though to not let your exception go outside of the bounds of your layer by converting the exception.
Use of the UnhandedException
During implementation you may find yourself in a situation where you find yourself with a checked exception clause but you don’t know how to handle it yet. Don’t log it with a “to do” message, instead convert it to an UnhandledException type and let it propagate. This will make sure that the exception still propagates and will be dealt with when the specs are clarified.
Avoid long catch clauses by homogenizing and refining exceptions
Every bracket adds complexity to your code, so you don’t want to catch every possible exception type that may propagate to your client code. You can for instance convert any data layer exception to a DataLayerException, but you can use subclassing to add more detail like a DuplicateKeyException. Only create subclasses when they add more detail that is useful for your client code. Don’t just subclass to be more specific about the type – when refining you should add value for the client code, like adding information that could be helpful for the end-user (available keys), or so that your client code can make a decision on trying the same operation again.
Avoid catching your Exception base class.
Exceptions need to propagate and if you catch your base Exception class in nested code, it is likely that in the long run exceptions don’t propagate anymore. This can cause a lot of undesired behavior that is very hard to locate and to fix. Unless the exceptions are checked and your client code can handle them, avoid suppressing (or even worse, ignoring) exceptions, they are thrown for a reason.
Dealing with exceptions is an important but often ignored part of the software development cycle. Then informing the user about how to deal with them is probably just as important. Develop a good strategy and use the practices listed in this post – they have worked for us. If you have any good resources to share about exception handling strategies that worked for you, please leave them in the comments. If you learned something from this post – please share it with your friends and colleagues!