在具有 spring rest 的全局异常处理程序中使用 Generic Exception class 处理程序是一种好习惯吗?

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

我参考了几篇使用 @ControllerAdvice 创建全局异常处理程序的文章,我的其余 api 项目使用 spring。这样做的目的是在发生异常的情况下向客户端发送正确格式的响应。在一些文章中,他们在全局异常处理程序中添加了 ThrowableException。 我应该用 RunTimeException 替换它吗,因为这个块是针对运行时发生的异常?

异常处理程序代码:

@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;
    }
}

错误响应代码:

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;
    }
}  

参考文献:

  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

Should I replace it with RunTimeException as this block is for exception occurred at runtime?

为了确保您捕获任何抛出但从未被您的组件处理过的异常或任何类型异常比 Exception 更类型化的异常处理程序,您应该有一个 Exception.[= 的处理程序23=] RuntimeException 的处理程序是不够的,因为在运行时也会抛出已检查的异常,并且如果高级组件的方法声明指定 throws Exceptionthrows "any checked exception",则会传播已检查的异常,直到客户端或此处将应用默认行为的容器。
例如,想象一下可以使这种情况发生的其余控制器方法声明:

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Foo> getOne(@PathVariable long id) throws Exception {
       // ....           
}

要覆盖此默认 Spring 行为,您需要为 Exception 添加一个处理程序。
当然,这并不意味着只为 Exception 声明一个处理程序就是这种方式,但您可能会遇到一些没有特定处理的异常,并且通用处理就可以了。

老实说,有一个异常处理程序句柄 Exception 对我来说似乎有点懒惰。由于选中 Exception,您应该负责处理错误或从错误中恢复。如果你不能从错误中恢复,或者你所处的环境阻止你编写允许你优雅地恢复的代码,它应该在 RuntimeException 而不是指出问题。

当然,异常处理程序有两个目的:

  • 它们使您能够定义错误响应的外观及其详细内容的标准。
  • 它们使您能够记录错误,以便您稍后返回并修复它。

我强烈建议将已检查的 Exception 重新抛出为未检查的模式,并在异常处理程序中处理这些模式。作为一个万能的万能保险,您可以使用 Exception 的通用异常处理程序来捕获所有未转换的点,并记录发生的情况。

绝不会您作为开发人员允许 Exception 在没有明确原因的情况下一直传播到顶部。