Java - find the first cause of an exception

最后都变了- 提交于 2019-11-28 07:12:46

Just traverse the exception chain until you get to an exception with no cause, and then just return that message, if you want the last one.

Your function will only get the first cause, if there is one.

You may want to look at finding the first cause in your package though, as the actual deepest one may be an oracle exception, which is helpful, but unless you can see where you created the problem, you will have a hard time fixing it.

Cowan

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!)

If you are already on Guava than Throwables.getRootCause() comes to the rescue.

vickirk

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

I think that any error that is thrown by oracle will be wrapped in a SQLException (somebody please correct me if wrong). Once you have accessed the SQLException you should be able to call

getErrorCode() Retrieves the vendor-specific exception code for this SQLException object.

Let me know if this works as I have never tried it :-)

Karl

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

you can use the getStackTrace() from the Throwable class. This would give you the stack of StackTraceElements to work with. You can iterate through the StackTraceElements[] to find "ORA" string.

Let me know if you need an example.

spork

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!