When to Choose Checked and Unchecked Exceptions

When to choose checked and unchecked exceptions

Checked Exceptions are great, so long as you understand when they should be used. The Java core API fails to follow these rules for SQLException (and sometimes for IOException) which is why they are so terrible.

Checked Exceptions should be used for predictable, but unpreventable errors that are reasonable to recover from.

Unchecked Exceptions should be used for everything else.

I'll break this down for you, because most people misunderstand what this means.

  1. Predictable but unpreventable: The caller did everything within their power to validate the input parameters, but some condition outside their control has caused the operation to fail. For example, you try reading a file but someone deletes it between the time you check if it exists and the time the read operation begins. By declaring a checked exception, you are telling the caller to anticipate this failure.
  2. Reasonable to recover from: There is no point telling callers to anticipate exceptions that they cannot recover from. If a user attempts to read from an non-existing file, the caller can prompt them for a new filename. On the other hand, if the method fails due to a programming bug (invalid method arguments or buggy method implementation) there is nothing the application can do to fix the problem in mid-execution. The best it can do is log the problem and wait for the developer to fix it at a later time.

Unless the exception you are throwing meets all of the above conditions it should use an Unchecked Exception.

Reevaluate at every level: Sometimes the method catching the checked exception isn't the right place to handle the error. In that case, consider what is reasonable for your own callers. If the exception is predictable, unpreventable and reasonable for them to recover from then you should throw a checked exception yourself. If not, you should wrap the exception in an unchecked exception. If you follow this rule you will find yourself converting checked exceptions to unchecked exceptions and vice versa depending on what layer you are in.

For both checked and unchecked exceptions, use the right abstraction level. For example, a code repository with two different implementations (database and filesystem) should avoid exposing implementation-specific details by throwing SQLException or IOException. Instead, it should wrap the exception in an abstraction that spans all implementations (e.g. RepositoryException).

How do you judge whether to make an exception checked or unchecked?

The meaning of the quote is this: If the client code can not recover from the problem, it needs to let the exception propagate to higher layers. If you use checked exceptions for that, you need to declare the checked exception through all call layers without benefit.

To rephrase the quote: If the exception is expected to propagate through the layers, make it unchecked. Only make it checked if the caller can actually do something about it.

Comparing checked and unchecked exceptions (Performance, Benchmarks) in Java

From the perfomance point of view, building stack trace for exception is anyway the longest operation when an exception is generated (details).

Checked and unchecked exceptions make difference only at compile time. The Java compiler forces you to either catch checked exceptions or declare them in the method signature. It was supposed to improve program safety, but the majority opinion seems to be that it's not worth the design problems it creates.

There is even Lomboks "magical" @SneakyThrows annotation to overcome this compile-time check. On the JVM (class file) level, all exceptions, checked or not, can be thrown regardless of the throws clause of your methods, which is why this works.

Using Checked Exceptions vs Unchecked Exceptions with REST APIs

Q1: So the API User is also considered as a "Client code"?

Yes.

Q2: For request validations, should I throw Checked or Unchecked Exceptions?

Quoting from the advice in your question: "If the Client code cannot do anything, Make it an unchecked exception. And if the Client code will take some useful recovery action based on information in the exception, make it a checked exception."

Q3: Is the best practice to avoid using checked exceptions?

No.

Q4: Is is ok to throw unchecked exceptions in validations, and let it bubble up, and catch and wrap it with in a custom exception at the Service Layer? (and use JAX-RS ExceptionMapper [3] to show that to the API user)

"Is it OK" depends on who you ask. It also depends on whether it works for you.

If you turn everything into unchecked exceptions, then the compiler cannot help you by checking that exceptions that ought to be handled are handled.

In your model, something must sort out the errors that need to be handled by the caller of the client API from those that don't. It can be done ... but you are much more dependent on the API client programmer to know what is the right things to do. Without checked exceptions, he / she is able to simply ignore the exceptions ... until they cause system test failures, failures in production.

How good are your programmers? How good is your documentation? How good is your quality control / testing regime?



Related Topics



Leave a reply



Submit