How to return http status code for exceptions in rest services
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.
Comments
-
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 almost 9 yearsHi, Thanks for a quick reply :) I have updated the question.
-
Sunil Rk almost 9 yearsis 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 almost 9 yearsNo 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 almost 9 yearsoh 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 almost 9 yearsYes 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 writetry...catch
statements. But you need to integrate aop, if you did not already -
Sunil Rk almost 9 yearsThanks for the clarification, it helped a lot .. :)
-
Raf about 4 yearsConflictException 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)