---
layout: post
title: Java Efficient Patterns for Exception Handling
image: /assets/Parachute.png
date: 2023-03-05 16:19:53 +0100
categories:
- Java
---
Error handling is one of the most crucial parts of any application.
In this article, which results from a lot of research and insights (and some experience in the field),
we will see 4 peculiar patterns/best practices for handling errors or exceptions in Java.
{% include image.html src="/assets/Parachute.png" alt="A parachute" caption="Photo by Julian Bock on Unsplash" %}
## 1- Exception Wrapper Pattern
**How**: All exceptions thrown by methods in a peculiar package should be wrapped into peculiar exceptions.
**When**: This pattern is very useful if the code is to be shipped in the form of Java libraries, or if it includes several packages, all of which don’t have the same business logic. If your code is simple enough or does not provide any kind of libraries, using this pattern is not advisable as it will increase abstraction.
**Why**: Re-throwing exceptions will show implementation details to the client, which should be hidden. The client of the code should not be required to modify the catch cause for every update of the service code. Remember that the throw cause is part of the signature of the method, and any changes to the signature will impact the client. Say you have a large user-base for your package, this will result in a huge refactor.
**Example**: For their DAO support, Spring defines a consistent exception hierarchy hiding and wrapping low-level exceptions as Hibernate-specific exceptions, SQL Exceptions, etc.
{% include image.html src="/assets/DataAccessException.gif" alt="Data access exception hierarchy" caption="Image Source" %}
**Pattern Extensions:** This pattern works by wrapping any exception in a specific runtime package exception. In this way, any boilerplate “try-catch“ code is removed. This pattern is very useful if no exception to the service package is recoverable (I recommend using checked exceptions only if the client can take some useful recovery action based on information in the exception. Otherwise the right choice is unchecked exceptions). The implementation is very simple and straightforward using [lombok @SneakyThrows](https://projectlombok.org/features/SneakyThrows).
**References:**
1. [http://wiki.c2.com/?HomogenizeExceptions](http://wiki.c2.com/?HomogenizeExceptions)
2. [http://wiki.c2.com/?ConvertExceptions](http://wiki.c2.com/?ConvertExceptions)
3. [http://tutorials.jenkov.com/java-exception-handling/exception-wrapping.html](http://tutorials.jenkov.com/java-exception-handling/exception-wrapping.html)
4. [https://stackoverflow.com/questions/484794/wrapping-a-checked-exception-into-an-unchecked-exception-in-java](https://stackoverflow.com/questions/484794/wrapping-a-checked-exception-into-an-unchecked-exception-in-java)
---
## 2- Fault Barrier Pattern
First, let’s start by defining two kinds of errors in Java. First, we have to distinguish between FAULTS and CONTINGENCIES.
* Faults are non-recoverable errors to be handled with unchecked exceptions.
* Contingencies are recoverable errors to be handled with checked exceptions.
The fault barrier pattern is a pattern that handles faults.
**How**: “In the fault barrier pattern, any application component can throw a fault exception, but only the component acting as the ‘fault barrier’ catches them.” [Source](https://www.oracle.com/technical-resources/articles/enterprise-architecture/effective-exceptions-part2.html). The fault barrier component should record the information contained in the fault exception for future action (logging) and close out the operation in a controlled manner.
{% include image.html src="/assets/FaultBarrier.jpg" alt="Fault Barrier" caption="Image Source" %}
**When:** You should follow this pattern in every application that can fail in some way. Practically speaking, you’ll want to use this pattern in every application.
**Why**: The fault barrier pattern enables the separation of concerns. It centralizes the logic of unwanted and unchecked errors (faults) in a single place. It also frees the business logic of your application from the burden of error handling and avoids the repetition of code.
**Example**: In the Spring Framework, it is possible to define a global exception handler component for the other methods, which will handle all faults using the @ControllerAdvice annotation.
{% highlight java %}
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;
@ControllerAdvice
public class RestResponseEntityExceptionHandler
extends ResponseEntityExceptionHandler {
private static Logger LOGGER = LoggerFactory.getLogger(RestResponseEntityExceptionHandler.class);
@ExceptionHandler(value
= { IllegalArgumentException.class, IllegalStateException.class })
protected ResponseEntity