How to return http status code for exceptions in rest services

30,159

You can use exceptions defined in jax-rs or you can use your own exceptions. Fist catch your business exceptions and convert them to jax-rs versions. For example, for 404 you can throw javax.ws.rs.NotFoundException.

You can also write your own exceptions by extending them from javax.ws.rs.ClientErrorException

Here is an example for 409-Conflict status exception

import javax.ws.rs.ClientErrorException;
import javax.ws.rs.core.Response;

public class ConflictException extends ClientErrorException{

    public ConflictException(Response.Status status) {
        super(Response.Status.CONFLICT); // 409
    }
}

Update

Most simple and feasible way is catching your business exceptions and re-throw them with jax-rs exceptions.

try{
  businessService.executeBusinessRule();
}catch (BusinessException e){
  // It is better if your BusinessException has some child class to handle
  if(e.getError() == ErrorEnumeration.VALIDATION_FAILED){
    throw new BadRequestException();
  }else{
    throw new ConflictException();
  }
}

If you are using spring you can always catch these exceptions using aop.

@Aspect
public class BusinessExceptionInterceptor{
@AfterThrowing(pointcut = "execution(* com.your.service.packge..* (..))", throwing = "e")
public void errorInterceptor(BusinessException e) {
   // re-throw again...
}

Update 2

Also it is better to define a new exception instead of reusing same exception with different state. You can define a new ValidationException which extends from BusinessException like this.

public class ValidationException extends BusinessException{

    public ValidationException() {
        super(ErrorEnumeration.VALIDATION_FAILED);
    }
}

By using this way you can still handle all the BusinessException but it is easier to identify or map them to Jax-rs exceptions.

Share:
30,159
Sunil Rk
Author by

Sunil Rk

Java Developer.

Updated on March 07, 2020

Comments

  • Sunil Rk
    Sunil Rk about 4 years

    In my application I have different layers like the rest layer, service layer and DB layer, according to business scenarios I am trowing different business exceptions from the service layer.

    But now, I have to set different HTTP codes like 400, 403, 409, 412.. to REST responses.

    How can I set different HTTP status codes based on different scenarios?

    Which is the most feasible way like: aspect, exception mapper, or ....?

    Since I can set HTTP status only once in rest layer ( referred this ), I am not able to map to different HTTP codes because my exception is from service layer.

    My exception class looks like this:

    public class BusinessException extends RuntimeException {
        private static final long serialVersionUID = 1L;
    
        public BusinessException(ErrorEnumeration error) {
    
        }
        public BusinessException(Exception e, ErrorEnumeration error) {
    
        }
    }
    

    and the exception will be thrown from the service like this:

     throw new BusinessException(ErrorEnumeration.VALIDATION_FAILED);
    

    Please help by suggesting a solution

  • Sunil Rk
    Sunil Rk almost 9 years
    Hi, Thanks for a quick reply :) I have updated the question.
  • Sunil Rk
    Sunil Rk almost 9 years
    is it good add one more method in my "BusinessException" class like below ? public BusinessException(ErrorEnumeration error, Response.Status httpStatus) { } So that i can send the status while throwing itsef.
  • bhdrkn
    bhdrkn almost 9 years
    No not good. Your business layer should not be aware of which layer using it. You must detailed your exceptions, then handle them properly and last rethrow them in a form with status code.
  • Sunil Rk
    Sunil Rk almost 9 years
    oh ok, but if i want to re-throw as u said i have to write catch or new exception class (referring your answer).Problem is i have around 35 different enumerations according business scenarios, i can't catch 35 exceptions for re-mapping or creating new classes also not recommendable.In this case how can i move ahead ?
  • bhdrkn
    bhdrkn almost 9 years
    Yes that will be a problem :). Just catch them with businessException exception. Then write a utility which generates exceptions according to your enumeration. You may use aop to catch them. This way you do not need to write try...catch statements. But you need to integrate aop, if you did not already
  • Sunil Rk
    Sunil Rk almost 9 years
    Thanks for the clarification, it helped a lot .. :)
  • Raf
    Raf about 4 years
    ConflictException is not in Jersey 2 anymore. I am digging to see what I can replace it with (after attempts to migrate from Jersey 1.18 to 2.16)