Catching an exception that is nested into another exception

后端 未结 7 1602
暗喜
暗喜 2020-12-05 10:18

I want to catch an exception, that is nested into another exception. I\'m doing it currently this way:

} catch (RemoteAccessException e) {
    if (e != null          


        
7条回答
  •  臣服心动
    2020-12-05 10:20

    I just solved a problem like this by writing a simple utility method, which will check the entire caused-by chain.

      /**
       * Recursive method to determine whether an Exception passed is, or has a cause, that is a
       * subclass or implementation of the Throwable provided.
       *
       * @param caught          The Throwable to check
       * @param isOfOrCausedBy  The Throwable Class to look for
       * @return  true if 'caught' is of type 'isOfOrCausedBy' or has a cause that this applies to.
       */
      private boolean isCausedBy(Throwable caught, Class isOfOrCausedBy) {
        if (caught == null) return false;
        else if (isOfOrCausedBy.isAssignableFrom(caught.getClass())) return true;
        else return isCausedBy(caught.getCause(), isOfOrCausedBy);
      }
    

    When you use it, you would just create a list of if's from most specific Exception to least specific, with a fallback else-clause:

    try {
      // Code to be executed
    } catch (Exception e) {
      if (isCausedBy(e, MyException.class)) {
        // Handle MyException.class
      } else if (isCausedBy(e, AnotherException.class)) {
        // Handle AnotherException.class
      } else {
        throw new IllegalStateException("Error at calling service 'service'");
      }
    }
    

    Alternative/Addition per requests in comments

    If you want to use a similar method to get the Exception object of the class you're looking for, you can use something like this:

      private boolean getCausedByOfType(Throwable caught, Class isOfOrCausedBy) {
        if (caught == null) return null;
        else if (isOfOrCausedBy.isAssignableFrom(caught.getClass())) return caught;
        else return getCausedByOfType(caught.getCause(), isOfOrCausedBy);
      }
    

    This could be used in addition to isCausedBy() this way:

      if (isCausedBy(e, MyException.class)) {
        Throwable causedBy = getCausedBy(e, MyException.class);
        System.err.println(causedBy.getMessage());
      }
    

    It can also used directly instead of isCausedBy(), although it's probably a matter of opinion whether this is more readable.

      Throwable causedBy;
      if ((causedBy = getCausedBy(e, IllegalAccessException.class)) != null) {
        System.err.println(causedBy.getMessage());
      }
    

提交回复
热议问题