Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return http status code for exceptions in rest services

Tags:

java

rest

http

cxf

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

like image 607
Sunil Rk Avatar asked Jun 23 '15 07:06

Sunil Rk


People also ask

How do I return an exception from Web API?

Return InternalServerError for Handled Exceptionscs file and locate the Get(int id) method. Add the same three lines within a try... catch block, as shown in Listing 2, to simulate an error. Create two catch blocks: one to handle a DivideByZeroException and one to handle a generic Exception object.

How do I return status codes in spring rest?

Spring provides a few primary ways to return custom status codes from its Controller classes: using a ResponseEntity. using the @ResponseStatus annotation on exception classes, and. using the @ControllerAdvice and @ExceptionHandler annotations.

What is status code 204 in API?

The HTTP 204 No Content success status response code indicates that a request has succeeded, but that the client doesn't need to navigate away from its current page. This might be used, for example, when implementing "save and continue editing" functionality for a wiki site.

Which HTTP status code is returned after a successful REST API request?

The create action is usually implemented via HTTPs POST method. In RESTful APIs, these endpoints are used to create new resources or access tokens. 200 OK - It's the basic status code to tell the client everything went good.


1 Answers

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.

like image 140
bhdrkn Avatar answered Sep 22 '22 12:09

bhdrkn