关于 @ExceptionHandler(Exception.class) 的问题

huangapple go评论66阅读模式
英文:

Question about @ExceptionHandler(Exception.class)

问题

以下是翻译好的部分:

在处理异常的时候,有一个异常拦截器:

我被要求在用户尝试从数据库中删除违反完整性约束的对象时,向用户返回友好的错误消息。

我捕获了 DataIntegrityViolationException 异常并实现了这个任务。

我原本以为会失败,因为有 @ExceptionHandler(Exception.class),这会首先拦截错误。

我的问题是,为什么它按我期望的方式工作了呢?
为什么 @ExceptionHandler(Exception.class) 没有首先捕获这个异常?

总的来说,当 @ExceptionHandler(Exception.class) 拦截了本应该命中另一个拦截器的异常时,应该怎么办?或者只有在另一个拦截器中有类似的 @ExceptionHandler(Exception.class) 结构时才可能出现这种情况吗?

SpringBoot 版本:2.1.9.RELEASE

英文:

There is an exception interceptor:

    @ControllerAdvice
    public class RestExceptionHandler extends ResponseEntityExceptionHandler {

        @ExceptionHandler
        public ResponseEntity<ApiExceptionDTO> handleDataIntegrityViolationException(DataIntegrityViolationException ex) {
            // return ResponseEntity<ApiExceptionDTO> with user friendly error message
        }

        // ... other @ExceptionHandler
        
        @ExceptionHandler(Exception.class)
        public ResponseEntity<ApiExceptionDTO> handleException(Exception ex) {
            // return ResponseEntity<ApiExceptionDTO>
        }

    }

I was tasked with returning a friendly error message to the user if he tries to delete an object from the database that violates the integrity constraint.

I caught the DataIntegrityViolationException exception and implemented the task.

I expected it to fail because of @ExceptionHandler(Exception.class), since it will intercept the error first.

My question is, why did it work the way I expected?
Why @ExceptionHandler(Exception.class) didn't catch this exception first?

And in general, the question is what to do in the case when @ExceptionHandler(Exception.class) intercepts exceptions that should have hit another interceptor? Or is it possible only if somewhere in another interceptor there is a similar construction @ExceptionHandler(Exception.class) ?

SpringBoot version: 2.1.9.RELEASE

答案1

得分: 1

为拦截器正常工作,您需要从代码中抛出DataIntegrityViolationException异常。但您之前自行处理了该异常。异常需要传播到顶层,以便由拦截器处理。
额外提示:在从代码中抛出异常时添加自定义消息,并从拦截器类中获取相同消息。

英文:

For an interceptor to work, You need to throw your DataIntegrityViolationException exception from the code. But you were handling that by yourself. Exceptions need to propagate to the top to be handled by your interceptor.
Additional tip: Add a custom message when you throw your exception from code and get the same from interceptor class.

答案2

得分: 1

@ControllerAdvice 会寻找最合适的 @ExceptionHandler。为此,它将使用抛出异常的类,然后检查是否有任何处理程序与之匹配。如果没有,它将重复这个过程,一直到找到处理程序为止,依次查找它的父类,然后再查找父类的父类,依此类推。

在这个特定情况下,它将首先寻找:
@ExceptionHandler(DataIntegrityViolationException.class)
然后是 @ExceptionHandler(NonTransientDataAccessException.class)
接着是 @ExceptionHandler(DataAccessException.class)
...
最后是 @ExceptionHandler(Exception.class)

英文:

The @ControllerAdvice will look for the most appropriate @ExceptionHandler. To do this, it will use the class of the exception which is being thrown and it will check if any of the handlers are going to match it. If not, it will repeat the process with the parent of your class, then it will do it with the parent of its parent, and so on until it finds a handler.

In this particular case, it will initially look for:
@ExceptionHandler(DataIntegrityViolationException.class)
then for @ExceptionHandler(NonTransientDataAccessException.class)
then for @ExceptionHandler(DataAccessException.class)
...
and, lastly, for @ExceptionHandler(Exception.class)

huangapple
  • 本文由 发表于 2023年2月27日 18:56:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75579551.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定