Wrapping Exception

Java exceptions are language features used to deal with program failure. In this article, we will see one of the best practices of exception handling followed in the industry called “Exception wrapping” or “Exception funnelling”.

Introduction

Exception wrapping is when you catch an exception, wrap it in another exception and throw that exception. In the following section, we see both the scenarios with and without exception wrapping.

Without exception wrapping

Disadvantage

  1. The main disadvantage of not having the exception wrapping is that declared exceptions get aggregated at the top of the call stack. In the example below, we have an Interface EmployeeDAO which has a method getList(), which throws SQLException, ConnectionException and IOException corresponding to each implementation of EmployeeDAO interface.
  2. Another disadvantage is that the upper layers in the call stack get to know the implementation details of the layers below it which is not desired.

The above scenarios are simulated with the example code block below.

package com.manoj.dao.withoutwrapping;

import java.io.IOException;
import java.net.ConnectException;
import java.sql.SQLException;
import java.util.List;

import com.manoj.entity.Employee;

public interface EmployeeDAOWithoutWrap {
  
  List<Employee> getList() throws SQLException, IOException, ConnectException;
}
package com.manoj.db;

import java.sql.SQLException;
import java.util.List;

import com.manoj.dao.withoutwrapping.EmployeeDAOWithoutWrap;
import com.manoj.entity.Employee;

public class EmployeeDataBaseImplWithoutWrap implements EmployeeDAOWithoutWrap {

  @Override
  public List<Employee> getList() throws SQLException {
    throw new SQLException();
  }
}
package com.manoj.ws;

import java.net.ConnectException;
import java.util.List;

import com.manoj.dao.withoutwrapping.EmployeeDAOWithoutWrap;
import com.manoj.entity.Employee;

public class EmployeeWebServiceImplWithoutWrap implements EmployeeDAOWithoutWrap {

  @Override
  public List<Employee> getList() throws ConnectException {
    throw new ConnectException();
  }
}
package com.manoj.file;

import java.io.IOException;
import java.util.List;

import com.manoj.dao.withoutwrapping.EmployeeDAOWithoutWrap;
import com.manoj.entity.Employee;

public class EmployeeFileImplWithoutWrap implements EmployeeDAOWithoutWrap {

  @Override
  public List<Employee> getList() throws IOException {
    throw new IOException();
  }
}

With exception wrapping

Below code block shows exception wrapping in action.

Interface EmployeeDAO has a method getList(), which throws only custom exception EmployeeDAOException.

package com.manoj.dao;

import java.util.List;

public interface EmployeeDAO {
  List<Employee> getList() throws EmployeeDAOException;
}

Classes EmployeeDataBaseImpl, EmployeeWebServiceImpl and EmployeeFileImpl implements EmployeeDAO interface.

In the method getList implementation we catch the SQLException or WebServiceException or IOException, wrap it and throw EmployeeDAOException.

package com.manoj.db;

import java.sql.SQLException;
import java.util.List;

import com.manoj.dao.Employee;
import com.manoj.dao.EmployeeDAO;
import com.manoj.dao.EmployeeDAOException;

public class EmployeeDataBaseImpl implements EmployeeDAOWithWrap {

  @Override
  public List<Employee> getList() throws EmployeeDAOException {
    try {
      throw new SQLException();
    } catch (SQLException sqlException) {
      sqlException.printStackTrace();
      throw new EmployeeDAOException("Difficulty in getting the Employee List", sqlException);
    }
  }
}
package com.manoj.ws;

import java.util.List;

import javax.xml.ws.WebServiceException;

import com.manoj.dao.Employee;
import com.manoj.dao.EmployeeDAO;
import com.manoj.dao.EmployeeDAOException;

public class EmployeeWebServiceImpl implements EmployeeDAOWithWrap {

  @Override
  public List<Employee> getList() throws EmployeeDAOException {
    try {
      throw new WebServiceException();
    } catch (WebServiceException webServiceException) {
      throw new EmployeeDAOException("Difficulty in getting the Employee List", webServiceException);
    }
  }
}
package com.manoj.file;

import java.io.IOException;
import java.util.List;

import com.manoj.dao.withwrapping.EmployeeDAOWithWrap;
import com.manoj.dao.withwrapping.EmployeeDAOException;
import com.manoj.entity.Employee;

public class EmployeeFileImpl implements EmployeeDAOWithWrap {

  @Override
  public List<Employee> getList() throws EmployeeDAOException {
    try {
      throw new IOException();
    } catch (IOException ioException) {
      throw new EmployeeDAOException("Difficulty in getting the Employee List", ioException);
    }
  }
}

We have created a custom exception EmployeeDAOException which extends Exception class to wrap the exceptions thrown in the below layers.

package com.manoj.dao;

public class EmployeeDAOException extends Exception {

  private static final long serialVersionUID = 1L;

  public EmployeeDAOException() {
    super();
  }

  public EmployeeDAOException(String message, Throwable cause, boolean enableSuppression,
      boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
  }

  public EmployeeDAOException(String message, Throwable cause) {
    super(message, cause);
  }

  public EmployeeDAOException(String message) {
    super(message);
  }

  public EmployeeDAOException(Throwable cause) {
    super(cause);
  }
}

 

 

Manoj Kumar

Manoj Kumar is a technology evangelist and he is currently working as a trainer at NPN Training. He is having 6+ years of experience in companies like Infosys & Mindtree. He has delivered complex projects using technologies like Java, Spring, Hibernate, Micro Services and Hadoop.