title: Correct way to handle exceptions in Spring Boot
body: <p>I was reading the Spring docs and found that creating a subclass from <code>ResponseEntityExceptionHandler</code> was a good way on handling exceptions. However, I tried to handle exceptions in a different way, since I need to diff <code>BusinessExceptions</code> from <code>TechnicalExceptions</code>. </p>
  
  <p>Created a bean called <code>BusinessFault</code> which encapsulates the exception details:</p>
  
  <p><strong>BusinessFault.java</strong> </p>
  
  <pre><code>import com.fasterxml.jackson.annotation.JsonInclude;
  import com.fasterxml.jackson.annotation.JsonInclude.Include;
  import com.fasterxml.jackson.annotation.JsonProperty;
  
  @JsonInclude(value = Include.NON_NULL)
  public class BusinessFault {
  
      @JsonProperty(value = "category")
      private final String CATEGORY = "Business Failure";
      protected String type;
      protected String code;
      protected String reason;
      protected String description;
      protected String instruction;
  
      public BusinessFault(String type, String code, String reason) {
          this.type = type;
          this.code = code;
          this.reason = reason;
      }
  
      public BusinessFault(String type, String code, String reason, String description, String instruction) {
          this.type = type;
          this.code = code;
          this.reason = reason;
          this.description = description;
          this.instruction = instruction;
      }
  
      public String getType() {
          return type;
      }
  
      public void setType(String type) {
          this.type = type;
      }
  
      public String getCode() {
          return code;
      }
  
      public void setCode(String code) {
          this.code = code;
      }
  
      public String getReason() {
          return reason;
      }
  
      public void setReason(String reason) {
          this.reason = reason;
      }
  
      public String getDescription() {
          return description;
      }
  
      public void setDescription(String description) {
          this.description = description;
      }
  
      public String getInstruction() {
          return instruction;
      }
  
      public void setInstruction(String instruction) {
          this.instruction = instruction;
      }
  
      public String getCATEGORY() {
          return CATEGORY;
      }
  }
  </code></pre>
  
  <p>Created a <code>BusinessException</code> class, which do the job by creating a <code>BusinessFault</code> beans through the details passed by its constructor:</p>
  
  <p><strong>BusinessException.java</strong></p>
  
  <pre><code>import com.rest.restwebservices.exception.fault.BusinessFault;
  
  public abstract class BusinessException extends RuntimeException {
  
      private BusinessFault businessFault;
  
      public BusinessException(String type, String code, String reason) {
          this.businessFault = new BusinessFault(type, code, reason);
      }
  
      public BusinessException(String type, String code, String reason, String description, String instruction) {
          this.businessFault = new BusinessFault(type, code, reason, description, instruction);
      }
  
      public BusinessException(BusinessFault businessFault) {
          this.businessFault = businessFault;
      }
  
      public BusinessFault getBusinessFault() {
          return businessFault;
      }
  
      public void setBusinessFault(BusinessFault businessFault) {
          this.businessFault = businessFault;
      }
  }
  </code></pre>
  
  <p>Created a specific <code>UserNotFoundException</code> class, which extends from <code>BusinessException</code> class:</p>
  
  <p><strong>UserNotFoundException.java</strong></p>
  
  <pre><code>import com.rest.restwebservices.exception.fault.BusinessFault;
  import com.rest.restwebservices.exception.map.ExceptionMap;
  
  public class UserNotFoundException extends BusinessException {
  
      public UserNotFoundException(BusinessFault businessFault) {
          super(businessFault);
      }
  
      public UserNotFoundException(String reason) {
          super(ExceptionMap.USERNOTFOUND.getType(), ExceptionMap.USERNOTFOUND.getCode(), reason);
      }
  
      public UserNotFoundException(String reason, String description, String instruction) {
          super(ExceptionMap.USERNOTFOUND.getType(), ExceptionMap.USERNOTFOUND.getCode(), reason, description,
                  instruction);
      }
  }
  </code></pre>
  
  <p>Created a <code>BusinessExceptionHandler</code>, but instead of being a subclass of <code>ResponseEntityExceptionHandler</code>, it's only has a <code>@ControllerAdvice</code> annotation and a method that handles all thrown <code>BusinessExceptions</code>:</p>
  
  <p><strong>BusinessExceptionHandler.java</strong></p>
  
  <pre><code>import javax.servlet.http.HttpServletRequest;
  
  import org.springframework.http.HttpStatus;
  import org.springframework.http.ResponseEntity;
  import org.springframework.web.bind.annotation.ControllerAdvice;
  import org.springframework.web.bind.annotation.ExceptionHandler;
  import org.springframework.web.bind.annotation.ResponseBody;
  
  import com.rest.restwebservices.controller.UserController;
  import com.rest.restwebservices.exception.BusinessException;
  import com.rest.restwebservices.exception.fault.BusinessFault;
  
  @ControllerAdvice(basePackageClasses = UserController.class)
  public class BusinessExceptionHandler {
  
      @ExceptionHandler(BusinessException.class)
      @ResponseBody
      public ResponseEntity&lt;BusinessFault&gt; genericHandler(HttpServletRequest request, BusinessException ex) {
          return new ResponseEntity&lt;BusinessFault&gt;(ex.getBusinessFault(), HttpStatus.OK);
      }
  }
  </code></pre>
  
  <p>The service layer can throw a <code>UserNotFoundException</code>:</p>
  
  <pre><code>@Service
  public class UserService {
  
      @Autowired
      private UserRepository userRepository;
  
      public User findById(Long id) {
          User user = userRepository.findOne(id);
          if (user == null)
              throw new UserNotFoundException("The ID " + id + " doesn't behave to any user!");
  
          return user;
      }
  }
  </code></pre>
  
  <p>It works fine. But I was wondering if this is a bad practice on handling exceptions?</p>