【问题标题】:Spring ExceptionHandler for Caused By / Wrapped ExceptionSpring ExceptionHandler for Caused By / Wrapped Exception
【发布时间】:2019-09-08 01:08:00
【问题描述】:

我找不到好的解决方案:在我的 Spring Boot 应用程序中,作为@ExceptionHandler 方法,我需要定义一个处理程序,不是针对特定异常,而是针对任何异常 一个特定的异常(即包装的异常)。

示例:有时我会这样:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:541) ~[spring-orm-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746) ~[spring-tx-5.1.4.RELEASE.jar:5.1.4.RELEASE]    
    ... 121 common frames omitted
Caused by: custom.TechRoleException: My custom TechRoleException
    at myapp.method1[..]
    at myapp.methodOuter[..]

我的自定义 TechRoleException 是我在一些 Hibernate EventListener 的预更新方法中抛出的异常,直接的异常是 Persistence 无法发生。

但是,从未达到以下尝试使用我的自定义异常的方法:

@ControllerAdvice
public class GlobalExceptionHandler {

  @ExceptionHandler(TechRoleException.class)
  public String techRoleException(HttpServletRequest request, Exception ex) {
    System.out.println("Got here");
    return "home";
  }
}

这是一个类似的帖子,其中答案是错误的并且没有回答这个问题: @ExceptionHandler for Wrapped Exception / getCause() in Spring

【问题讨论】:

  • ControllerAdvice 是完全不起作用还是在某些情况下不起作用?
  • 只是不为 Caused-By 工作,在所有其他情况下工作

标签: spring spring-boot spring-mvc exception


【解决方案1】:

我的最终工作答案是处理 General 异常,然后使用 Apache ExceptionUtils.getRootCause() 来检测我在这个常规处理程序中寻找的特定 Caused-By。

(其他特定的异常如果有专用的Handler就不会到这个方法。但是如果没有专用的Handler,异常就会到这里。)这是检测某些目标Caused-By的唯一方法。

@ExceptionHandler(Exception.class)
public String handleGeneralException(HttpServletRequest request, Exception ex) {

    Throwable rootCause = ExceptionUtils.getRootCause(ex);
    if (rootCause != null && "com.myapp.TechRoleException".equals(rootCause.getClass().getName())
    {       
        //... handle this Caused-By Exception here
        // ...
    }
    // All other exceptions that don't have dedicated handlers can also be handled below...
    // ...

}

【讨论】:

    【解决方案2】:

    也许是这样的?

    @ExceptionHandler(Exception.class)
    public String techRoleException(HttpServletRequest request, Exception ex) {
    if(ex instanceof TechRoleException) {
        System.out.println("Got here");
        return "home";
    } else {
        throw ex; //or something else
    }
    }
    

    【讨论】:

    • 请不要在这种情况下使用 Throwable,除非您还想捕获断言错误。使用例外。
    • 是的,行得通。我什至不需要为其他人“抛出 ex”,因为其他针对特定异常的专用处理程序会跳过此方法。
    • 我想过这个,但我不知道它是如何工作的:D 我不确定,但我认为我们应该使用:if(ex.getCause() instanceof TechRoleException)。或者最终使用 Apache 库方法 - Throwable getRootCause(Throwable throwable) 获取 rootCause,然后检查 instanceof。你怎么看?如果应用程序抛出异常(TransactionSystemException),那么带有TechRoleException的instanceof如何才能给我们true?我认为我们应该使用 ex.getCause() 或这个 apache 库来找到根本原因。如果需要,请检查它
    • 是的,我使用了 Apache ExceptionUtils getRootCause()。我会发布一个完整的答案。
    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 2022-11-18
    • 2022-12-22
    • 2022-01-16
    • 1970-01-01
    • 2023-02-17
    • 2012-10-27
    • 2015-11-14
    相关资源
    最近更新 更多