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 – Never lose the Stacktrace

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 an hierarchy similar to this one:

                                                                                     Exception

BusinessException

AccountingException

HumanResourcesException
BillingCodeNotFoundException

  EmployeeNotFoundException

11 Mistakes Java Developers make when Using Exceptions

5 Tips to Automate Test Effectively on Your Software and Prevent Bugs

1 – Test business rules from your methods

Well, what should be tested? Business rules, for sure! Don’t implement unitary tests to cover all methods and create numbers, make a real test!

Know your method and test it with meaningful flows where you can guarantee your logic is working.

Don’t implement meaningless tests.

2 – Give a clear, meaningful name to your method

Think about a great name for your test and choose the name that represents what you are testing.

Bad example:

@Test
public void test1()

Good example:

@Test
public void checkIfCustomerIsBlockedByFraudTest()

Much easier to understand, huh? You know your method is checking if the customer is blocked by fraud.

3 – If your method is too complex, use TDD (Test Driven Development)

Have you ever had to implement a very complex method? If so, it’s very difficult to test, right? To make implementation easier you should use TDD and implement your test before implementing your method. Use baby-steps, do the simplest thing first and then make your test work! Then keep going until your method is completely implemented!

The cool thing about using TDD is that your code is already tested! It’s amazing how it can help you! Just practice it, and see how amazing this is!

4 – Create your classes/methods with cohesion

Unitary tests help a lot to know if your code is good or bad. It’s very simple, if you can’t test your code easily, your code doesn’t have cohesion or low coupling.

If you are in this situation, refactor your code, don’t turn it into a big problem. If your code keeps on growing like this, you will have real problems to change features or implement something new.

If you implement a test for a method that is responsible for many actions, it will be completely useless. Anything you change on your method can break the test.

Avoid unnecessary stress by just refactoring your code.

5 – Know the difference between Unitary Tests and Integration Tests

What is the difference? Easy! Unitary Tests evaluate just one method. They test your code unitarily, method by method. You won’t use information from the database. You will “Mock” data, meaning you will create your own “fake” data to implement the test you need for your business rule. Although you can’t interact with the database, Unitary Tests are very fast and it’s possible to test business rules effectively.

Integrated tests, as the name says, are more complete tests. You will interact with the database. You will insert your own data into the database and test your services integrally. The cons are that it is slow, it takes time to test everything. You also take more time to implement the test. It’s necessary to create your own data directly in the database (insert script, delete script).

5 Tips to Automate Test Effectively on Your Software and Prevent Bugs