11 Mistakes Java Developers make when Using Exceptions

The problem: If you use Exceptions in the wrong way, bugs will be very difficult to find. If you always use generic Exceptions, how can other developers know what error has occurred? You have to understand why we use Exceptions and how to use them effectively!

See the 11 mistakes Java Developers make when using Exceptions.

First, let’s see the hierarchy of the Exception classes.

Checked Exceptions / Unchecked Exceptions

1 – Using only the Exception class

It’s a common mistake that developers specifically catch the Exception class for any error. It’s much more difficult to identify the error if you see only an Exception being caught. The solution to this problem is to create specific Exceptions – but watch out, not too specific!

2 – Creating lots of specific Exceptions

Don’t create Exceptions for everything. Your application will be full of classes, useless repetition and you will create unnecessary work. Instead, create Exceptions for really important business requirements. For example, if you are developing a bank system one possible Exception would be when trying to withdraw money and the balance is zero: BalanceNotAvailableException. Another Exception would be transferring money to another person and the account does not exist, you can create: BankAccountNotFoundException and show an understandable Exception message to the user.

RuntimeException could be used when the bank’s server is out of service. Here you can use, for example: ServerNotAvailableException. The system must crash for this kind of error. There is no recovery.

3 – Creating a log for every catch

Logging every Exception catch will pollute your code. To prevent this, just log once and throw your Exception in the last catch. You won’t lose your Stacktrace if you wrap the Exception. If you are working with web applications, you should create a catch on your controller layer and log the error.

4 – Not knowing the difference between Checked and Unchecked Exceptions

When should Checked Exceptions be used? Use Checked when there is a recoverable error or an important business requirement.

The most common Checked Exception is the Exception class. Two related classes from Exception are FileNotFoundException and SQLException.You are obligated to handle or declare these exceptions. You must throw or catch the Exception or else it won’t compile.

When should Unchecked Exceptions be used? Use Unchecked when there is no recovery. For example, when the memory of the server is overused.

RuntimeException is used for errors when your application can not recover. For example, NullPointerException and ArrayOutOfBoundsException. You can avoid a RuntimeException with an ‘if’ command. You should not handle or catch it.

There is also the class Error. It is an Unchecked Exception too. Never try to catch or handle this kind of Exception. They are errors from the JVM and are the most serious kind of Exception in Java. You must analyze the cause of Exceptions like this and change your code.

5 –  Silencing Exceptions

Never catch the Exception and do nothing, for example:

try {
    System.out.println("Never do that!");
} catch (AnyException exception) {
    // Do nothing

The catch will be useless. It’s impossible to know what happened and the Exception will be silenced. The developer will be obliged to debug the code and see what happened. If we create a good log, the time-consuming analysis won’t be necessary.

6 – Not following the principle “throw early, catch late”

If you have to handle Exception, for example, in your Service, you should do two things:

  1. Wrap your Exception
  2. Throw the Exception to the last catch and handle it.

7 – Not using clear messages on the Exceptions

Always use clear messages on your Exceptions. Doing this will help a lot when finding errors. Even better, create a Properties File with all Exception messages. You can use the file on your View layer and show users messages about the business requirements.

8- Not cleaning up after handling the Exception

After using resources like files and database connection, clean them and close them so that you won’t harm the system’s performance. You can use the finally block to do it.

9 – Not documenting Exceptions with javadoc

To avoid headaches, always Document why the Exception is being thrown in your method. Document your Exception and explain why you created it.

10 – Losing the Stack Trace (root cause) 

When wrapping an Exception in another one, don’t just throw the other Exception, keep the Stacktrace.

Bad code:

try {
    // Do the logic
} catch (BankAccountNotFoundException exception) {
    throw new BusinessException();

Good code:

try {
    // Do the logic
} catch (BankAccountNotFoundException exception) {
    throw new BusinessException(exception);

11 – Not organizing the hierarchy of specific Exceptions

If you don’t organize the hierarchy of your Exceptions, the relationship will be difficult between the parts of the system. You will have lots of problems.

You should use a hierarchy similar to this one:







There is more! You can get this FREE E-Book too!
No Bugs, No Stress – Create a Life-Changing Software Without Destroying Your Life

Keep up improving yourself!


11 Mistakes Java Developers make when Using Exceptions

17 thoughts on “11 Mistakes Java Developers make when Using Exceptions

  1. Awesome post! You might also like to add this another common mistake:

    Concurrent Modification Exception

    This exception occurs when a collection is modified while iterating over it using methods other than those provided by the iterator object. For example, we have a list of hats and we want to remove all those that have ear flaps:

    List hats = new ArrayList();
    hats.add(new Ushanka()); // that one has ear flaps
    hats.add(new Fedora());
    hats.add(new Sombrero());
    for (IHat hat : hats) {
    if (hat.hasEarFlaps()) {

    If we run this code, “ConcurrentModificationException” will be raised since the code modifies the collection while iterating it. The same exception may occur if one of the multiple threads working with the same list is trying to modify the collection while others iterate over it. Concurrent modification of collections in multiple threads is a natural thing, but should be treated with usual tools from the concurrent programming toolbox such as synchronization locks, special collections adopted for concurrent modification, etc. There are subtle differences to how this Java issue can be resolved in single threaded cases and multithreaded cases.

    Reference link: https://www.toptal.com/java/top-10-most-common-java-development-mistakes

    1. Wow!!! Really awesome!! I forgot this error!! Thank you very much for this, Cesar! I will add this mistake, it’s really important because I already been through this situation.

  2. fbaligand says:

    Concerning mistake 10, title should be “Loose the root cause stacktrace”.
    If you say “never loose”, that’s not a mistake 🙂

  3. Erik says:

    “RuntimeException could be used when the bank’s server is out of service. Here you can use, for example: ServerNotAvailableException.”

    I think a checked exception would be fine, if a user may be able to try again or use another bank, compare with IOException which may happen when a server is not available.

    RuntimeException should be used for programming errors, like NullPointerException or ArrayIndexOutOfBoundsException. This typically happens when a developer has called a method with invalid data, IllegalArgumentException, or in the wrong order and the object is in an invalid state, IllegalStateException.

    1. fbaligand says:

      I disagree with you Erik. Up to me, all technical errors should be RuntimeException.
      And this is not only my mind : Spring, Hibernate, and Java SE itself (since few time) have this mind.

      You can look at TransactionException (Spring), HibernateException, WebServiceException (JAX-WS).
      You spoke about IOException, well, since java 8, there is UncheckedIOException.

      1. Discussions! They are always welcome, it makes us think better about the concepts. We can see RuntimeExceptions in a simple way and just ask the question:

        Is the system supposed to recover itself after the Exception happens? If the answer is “no” the best option is to use RuntimeExeption.

  4. Anonymous says:

    Languages like phyton, Ruby does not have support for the checked exception and proven to have robust production software.
    As per the clean code book by Robert C Martin, the debate between checked and unchecked exception is over.
    The Checked Exception is a violation of open close principle. If you throw checked exception from the method from your code then all the caller of the method either should declare or throw the exception.
    This means that change at low level will impact on many higher level.

    Checked Exception has benefits (Critical Library), but comes with the cost of dependency. The dependency cost outweighs the benefit of checked exception in general application.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s