Tony
Tony

Reputation: 63

Java create custom exception class with specific status code

In Spring Boot, I create custom exception class with specific status code, and I call it to throw exception with code: 100 and message: "No have content" at controller, but output still returns "status": 500 and "error": "Internal Server Error"

AppException.java

public class AppException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private final Integer code;

    public AppException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }
}

UserController.java

@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping()
    public ApiResponseDto getAllUsers(Pageable pageable) {
        Page<User> users = userService.getAllUsers(pageable);

        if (users.getSize() < 0) {
            throw new AppException(100, "No have content");
        }

        return new ApiResponseDto(HttpStatus.OK.value(), users);
    }

Actual Output:

{
    "timestamp": 1550987372934,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "com.app.core.exception.AppException",
    "message": "No have content",
    "path": "/api/user"
}

My expectation:

{
    "timestamp": 1550987372934,
    "status": 100,
    "error": "No have content",
    "exception": "com.app.core.exception.AppException",
    "message": "No have content",
    "path": "/api/user"
}

Upvotes: 6

Views: 17782

Answers (3)

Selindek
Selindek

Reputation: 3423

If you need a limited number of different error-messages or you want to reuse the same one several times, then that's all you need:

@ResponseStatus(value = HttpStatus.CONTINUE, reason = "No have content")
public class AppException extends RuntimeException {
    private static final long serialVersionUID = 1L;
}

No need of any extra classes and handlers. Your code will be clear and simple.

You can simply raise it like this:

throw new AppException();

Upvotes: 3

Oleksii Zghurskyi
Oleksii Zghurskyi

Reputation: 4365

In case you want to have global exception handling for your API, and prefer to have custom error responses, you can add @ControllerAdvice:

@ControllerAdvice
public class ApiExceptionHandler {

    @ExceptionHandler({ ApiException.class })
    protected ResponseEntity<ApiErrorResponse> handleApiException(ApiException ex) {
        return new ResponseEntity<>(new ApiErrorResponse(ex.getStatus(), ex.getMessage(), Instant.now()), ex.getStatus());
    }
}

// you can put any information you want in ApiErrorResponse 
public class ApiErrorResponse {

    private final HttpStatus status;
    private final String message;
    private final Instant timestamp;

    public ApiError(HttpStatus status, String message, Instant timestamp) {
        this.status= status;
        this.message = message;
        this.timestamp = timestamp;
    }

    public HttpStatus getStatus() { 
        return this.status; 
    }

    public String getMessage() {
        return this.message;
    }

    public Instant getTimestamp() {
        return this.timestamp;
    }
}

// your custom ApiException class
public class ApiException extends RuntimeException {

    private final HttpStatus status;

    public ApiException(HttpStatus status, String message) {
        super(message);
        this.status = status;
    }

    public HttpStatus getStatus() {
        return this.status;
    }
}

Upvotes: 6

Markoorn
Markoorn

Reputation: 2565

There are multiple ways to achieve this:

  1. ExceptionHandler

    You can add a @ExceptionHandler annotated method in your controller:

    @ExceptionHandler({ CustomException1.class, CustomException2.class })
    public void handleException() {
    //
    }
    
  2. HandlerExceptionResolver

    You can also implement a custom resolver to intercept all exceptions and handle them globally by overriding the doResolveException method

More detail on the above two approaches can be found here: https://www.baeldung.com/exception-handling-for-rest-with-spring

Upvotes: 1

Related Questions