Handling exceptions with user-defined exceptions

Exception handling is one of the core and most important tasks for software developers. Is is used for various reasons from service input validation to data validation and business rules.

The most common way to handle errors is throwing Exception object for related cases. For instance, the service and its method below contains an input validation. Validating request(input) before processing the main task(here is ordering) is a known good practice:

public class OrderService {private static final int ORDER_SUCCESS = 0;public OrderResponse Order(OrderRequest request) throws Exception {  if (request.getCustomerId() == null) {     throw new Exception(“customerId can not be null”);  }  if (request.getItemId() == null) {    throw new Exception(“itemId can not be null”);  }  //process order  OrderResponse response = new OrderResponse();  response.setStatus(ORDER_SUCCESS);  return response; }}

Everything looks fine, but actually not. Even though the service runs correctly, it has a bad exception handling practice. Because we used the broadest exception type: Exception class. It causes eliminating(swallowing) specific errors and making you need to examine the problem line or debug the code.

And for the client side, they have to handle only one type of exception for all type errors. The other option is reading and parsing the error message and handle the specific error. It even may get client angry.

To solve this, you can create your own user-defined exceptions instead of using built-in exceptions.

Let’s create our exceptions. As you guess we need to define 2 exceptions. One of them is to handle customerId validation and the other one is to handle itemId validation. If the client send an invalid request we throw user-defined specific exceptions.

public class InvalidCustomerInfoException extends Exception{  public InvalidCustomerInfoException(String message) {    super(message);  }}public class InvalidItemInfoException extends Exception{  public InvalidItemInfoException(String message) {    super(message);  }}

Finally, we can refactor our service by using exceptions we defined:

public class OrderService {private static final int ORDER_SUCCESS = 0;  public OrderResponse Order(OrderRequest request) throws InvalidCustomerInfoException, InvalidItemInfoException {    if (request.getCustomerId() == null) {      throw new InvalidCustomerInfoException("customerId can not be       null");     }    if (request.getItemId() == null) {      throw new InvalidItemInfoException("itemId can not be null");    }    //process order    OrderResponse response = new OrderResponse();    response.setStatus(ORDER_SUCCESS);    return response;  }}

Software Architect