How can I loop through Exception getCause() to find root cause with detail message

How can I loop through Exception getCause() to find root cause with detail message



I am trying to call saveOrUpdate() in hibernate to save data. Since columns have unique index, so its throws ConstraintViolationException when I look through via Eclipse debugger.


saveOrUpdate()


ConstraintViolationException



Since root cause could be different for different exception while inserting data to table.

I wanted to know, how can I loop / traverse through getCause() to check what is the root cause of exception and its message.


getCause()



Update:

Thanks everyone for your kind response, thing is I want output like in below image:
enter image description here

I need to access detailMessage field.

(I am really sorry If could not make my question more clear.)



Thanks.





What do you call the "root cause" exactly? The DB-specific exception?
– fge
Jul 19 '13 at 13:23





@fge, Yes its DB specific exception and question is updated.
– agpt
Jul 19 '13 at 13:37






Maybe .getSQLException().getMessage() then?
– fge
Jul 19 '13 at 13:56


.getSQLException().getMessage()





@fge, thing is I do not know what kind of exception will be thrown, hence I used parent class Exception to catch any possible exception. so .getSQLException()... wont work I guess.
– agpt
Jul 19 '13 at 13:59


Exception


.getSQLException()...





Well, catch JDBCException then, or HibernateException. You should never catch Exception to begin with.
– fge
Jul 19 '13 at 14:09


Exception




8 Answers
8



The Apache ExceptionUtils provide the following method:


Throwable getRootCause(Throwable throwable)



as well as


String getRootCauseMessage(Throwable th)





You can find something similar in Guava's Throwables: getRootCause(Throwable) and getStackTraceAsString(Throwable)
– Paolo Fulgoni
Mar 31 '14 at 7:28


getRootCause(Throwable)


getStackTraceAsString(Throwable)





However Guava has an issue regarding db style exception, thus creating infinite loops.
– Brice
Jan 15 at 11:09



I normally use the implementation below instead of Apache's one.



Besides it complexity Apache's implementation returns null when no cause is found, which force me to perform an additional check for null.



Normally when looking for an exception's root/cause I already have a non-null exception to start with, which is for all intended proposes is the cause of the failure at hand, if a deeper cause can't be found.


Throwable getCause(Throwable e)
Throwable cause = null;
Throwable result = e;

while(null != (cause = result.getCause()) && (result != cause) )
result = cause;

return result;





Indeed its helpful ! :) Thanks !
– agpt
Mar 9 '15 at 5:56





I believe such answers should be prefered by the questioner and the community as opposed to the answers with only a tool or lib recommendation.
– Alex Erohin
Jun 5 '15 at 12:23





The implementation I provided above is guards you from cyclically chained exceptions of just one step in depth, meaning when the exception chains to itself e = e.getCause() (the most common and only situation I have met). Nevertheless apache's implementation will really guard your code from cyclic exception chains of any depth e = e.getCause().getCause()... etc .. .getCause();
– Legna
Jun 5 '15 at 21:30






in which cases (result != cause) will help?
– Kulbhushan Singh
Jun 30 '16 at 8:49






@KulbhushanSingh '(result != cause)' will help every single time 'result' has a non null cause. the condition/expression on the while statement evaluates in the following order: 1.- assign cause = result.getCause() 2.- evaluates the result of the assignment above for null. null != cause 3.- if cause == null the whole expression evaluates to false, otherwise it proceeds to 4.- evaluate (result != cause) and that's your result
– Legna
Nov 15 '16 at 0:09



Using java 8 Stream API, this can be achieved by:


Optional<Throwable> rootCause = Stream.iterate(exception, Throwable::getCause)
.filter(element -> element.getCause() == null)
.findFirst();



Note that this code is not immune to exception cause loops and therefore should be avoided in production.



Are you asking for something like this?


Throwable cause = originalException;
while(cause.getCause() != null && cause.getCause() != cause)
cause = cause.getCause();



or am I missing something?





Exception is basically of DB type exceptions. so above while loop goes in indefinite loop.
– agpt
Jul 19 '13 at 13:52





It can be N causes deep.... cause.getCause().getCause().getCause().. hence the need for something like Apache ExceptionUtils.getRootCause()
– johnm
Jun 2 '15 at 16:21



Guava's Throwables provides the following methods:


Throwables


Throwable getRootCause(Throwable throwable)



as well as


String getStackTraceAsString(Throwable throwable)


} catch (Exception ex)
while (ex.getCause() != null)
ex = ex.getCause();
System.out.println("Root cause is " + ex.getMessage());



Were you expecting something more complicated?





actually I am getting database regarding exception, so in that case above logic is not working. anyway thanks for your response. :)
– agpt
Jul 19 '13 at 13:50






This is not immune to loops - the case where an exception cause points to exception itself.
– prasopes
Mar 14 '14 at 17:18



In APACHE; the implementation is like below.



The highlight is list.contains(throwable) == false


public static Throwable getRootCause(final Throwable throwable)
final List<Throwable> list = getThrowableList(throwable);
return list.size() < 2 ? null : (Throwable)list.get(list.size() - 1);


public static List<Throwable> getThrowableList(Throwable throwable)
final List<Throwable> list = new ArrayList<Throwable>();
while (throwable != null && list.contains(throwable) == false)
list.add(throwable);
throwable = ExceptionUtils.getCause(throwable);

return list;



Try this, you can put this function in a kind of Util class:


public static Throwable getRootException(Throwable exception)
Throwable rootException=exception;
while(rootException.getCause()!=null)
rootException = rootException.getCause();

return rootException;



Example of usage :


catch(MyException e)
System.out.println(getRootException(e).getLocalizedMessage());



Source : How to get the root exception of any exception



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Some of your past answers have not been well-received, and you're in danger of being blocked from answering.



Please pay close attention to the following guidance:



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)