Reputation: 63
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
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
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
Reputation: 2565
There are multiple ways to achieve this:
ExceptionHandler
You can add a @ExceptionHandler
annotated method in your controller:
@ExceptionHandler({ CustomException1.class, CustomException2.class })
public void handleException() {
//
}
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