Java - find the first cause of an exception

后端 未结 10 800
渐次进展
渐次进展 2020-12-09 01:50

I need to check if an exception is caused by some database problem. I receive an Exception and check if its cause contains the \"ORA\" string and return that (something like

相关标签:
10条回答
  • 2020-12-09 02:11

    In the interests of not reinventing the wheel, if you're using Apache Commons Lang, then look at ExceptionUtils.getRootCause().

    Is it worth including a library just for that? Maybe not. But if you already have it on your classpath, it's there for you, and note that it does some things that a 'naive' implementation might not do (e.g. deal with cycles in the cause chain... ugh!)

    0 讨论(0)
  • 2020-12-09 02:11

    One line solution using core Java API:

        try {
            i = 1 / 0; 
        } catch (ArithmeticException e) {
            System.out.println(new ArithmeticException().initCause(e).getCause());
        }
    

    One more solution below works as well:

        try {
            i = 1 / 0; 
        } catch (ArithmeticException e) {
            System.out.println(new Exception().initCause(e).getCause());
        }
    

    Both of them will print

    java.lang.ArithmeticException: / by zero

    0 讨论(0)
  • 2020-12-09 02:11

    If the exception being thrown is always going to be of a specific type, like OracleException, you can catch just that exception.

    For example:

    try {
    
        ...
    
    } catch(OracleException oe) {
    
        ...
    
    }
    

    This would only apply if there are specific Oracle exceptions being thrown. I don't know much about Oracle, so before attempting this you will probably want to find out if that's what's happening.

    0 讨论(0)
  • 2020-12-09 02:13

    You could improve your code checking for SQLException

    import java.sql.SQLException;
    
    private static final String ORACLE = "ORA";
    
    public String doHandle(Throwable t) {
        if (t.getClass().isAssignableFrom(SQLException.class)) {
        SQLException e = (SQLException) t;
        int errCode = e.getErrorCode();
        String state = e.getSQLState();
        String msg = e.getMessage();
        if (msg.contains(ORACLE)) {
            return msg;
            }
        } else {
            if (t.getCause() != null) {
                return this.doHandle(t.getCause());
                }
            }
        return "";
    }
    

    Also, I think in Oracle "errCode" contains the number associated to ORA-nnnn

    0 讨论(0)
  • 2020-12-09 02:16

    on 28-01-2015 , i have unable to solve my problem with any of the above solution, so my recommendation is to use :

    e.getMessage().toString();
    

    Ps: i am using it on android.

    0 讨论(0)
  • 2020-12-09 02:18

    Probably a bit overkill for your usage but I think it is cleaner (and reusable)

    interface ThrowablePredicate {
        boolean accept(Throwable t);
    }
    
    public OracleErrorThrowablePredicate implements ThrowablePredicate {
        private static final ORA_ERR = "ORA";
    
        public boolean accept(Throwable t) {
            return t.toString().contains(ORA_ERR);
        }
    }
    
    
    public class CauseFinder {
    
       private ThrowablePredicate predicate;
    
       public CauseFinder(ThrowablePredicate predicate) {
          this.predicate = predicate;
       }
    
       Throwable findCause(Throwable t) {
          Throwable cause = t.getCause();
    
          return cause == null ? null 
             : predicate.accept(cause) ? cause : findCause(cause)
       }
    }
    
    
    // Your method
    private String getErrorOracle(Throwable e){
        return new CauseFinder(new OracleErrorThrowablePredicate()).findCause(e);
    }
    
    0 讨论(0)
提交回复
热议问题