问题
I was referring few articles to create global exception handler using @ControllerAdvice
for my rest api project using spring. The purpose of this is to send proper formatted response to the client in the case of exception occurred. In some articles they have added Throwable
or Exception
in global exception handler.
Should I replace it with RunTimeException
as this block is for exception occurred at runtime?
Exception Handler code:
@ControllerAdvice
public class GlobalExceptionHandler{
@ExceptionHandler(NoDataFoundException.class)
@ResponseStatus(code=HttpStatus.NOT_FOUND)
public ResponseEntity<ErrorResponse> handle(NoDataFoundException ex){
ErrorResponse errorResponse = new ErrorResponse(ex.getMessage(), HttpStatus.NOT_FOUND.value());
ResponseEntity<ErrorResponse> response = new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
return response;
}
..... more methods to handle custom exceptions
@ExceptionHandler(Exception.class)
@ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<ErrorResponse> handle(Exception ex){
ErrorResponse errorResponse = new ErrorResponse("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value());
ResponseEntity<ErrorResponse> response = new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
return response;
}
}
ErrorResponse code:
public class ErrorResponse {
private String message;
private int statusCode;
public ErrorResponse(String message, int statusCode) {
super();
this.message = message;
this.statusCode = statusCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatusCode() {
return statusCode;
}
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
}
References:
- https://dzone.com/articles/exception-handling-in-spring-boot-rest-web-service
- https://github.com/in28minutes/spring-boot-examples/tree/master/spring-boot-2-rest-service-exception-handling
回答1:
Should I replace it with RunTimeException as this block is for exception occurred at runtime?
To make sure that you catch any exception thrown and never handled by your components or any exception handler with a more typed exception than Exception
, you should have a handler for Exception
.
A handler for RuntimeException
is not enough because checked exception are also thrown at runtime and if the method declarations of your high level components specify throws Exception
or throws "any checked exception"
, a checked exception could be propagated until the client or here the container that will apply a default behavior.
For example imagine this rest controller method declaration that could be make this situation to happen :
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Foo> getOne(@PathVariable long id) throws Exception {
// ....
}
And to override this default Spring behavior, you will want to add a handler for Exception
.
Of course it doesn't mean that declaring a handler only for Exception
is the way but you may have some exception with no specific handling and for that a generic handling is fine.
回答2:
Honestly, having an exception handler handle Exception
seems a bit lazy to me. Since Exception
is checked, you should be responsible for handling or recovering from the error. If you're not able to recover from the error, or the circumstance you're in prevents you from writing code that allows you to elegantly recover, it should be re-thrown in a RuntimeException
instead to indicate the issue.
Of course, exception handlers serve two purposes:
- They give you the power to define a standard of how error responses look and what they contain in detail.
- They give you the ability to log the error so you can go back later and fix it.
I'd strongly encourage the pattern of re-throwing checked Exception
s as unchecked, and handling those in exception handlers. As a fail-safe catch-all, you can use a generic exception handler for Exception
to catch all of the spots that weren't converted over, and to log what happened.
It should never be the case that you as a developer allow an Exception
to propagate all the way to the top without explicit reason.
来源:https://stackoverflow.com/questions/52392820/is-it-good-practice-to-have-generic-exception-class-handler-in-global-exception