Is it good practice to have Generic Exception class handler in global exception handler with spring rest?

限于喜欢 提交于 2019-12-10 10:38:12

问题


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:

  1. https://dzone.com/articles/exception-handling-in-spring-boot-rest-web-service
  2. 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 Exceptions 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!