getCause() function of Throwable class (in Java) is not working as expected

I am getting null while calling the getCause function of Throwable.

package com.salman.demo;
public class MyClass {
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try {
            NormalClass.testIt();
        } catch (Throwable th) {
            System.out.println(th.getCause());
        }
    }
}


package com.salman.demo;

import com.salman.exceptions.ValidationException;

public class NormalClass {
    public static void testIt() throws ValidationException {
        System.out.println("Inside testIt funtion.");

        throw new ValidationException("Validation Exception..");
    }
}

On running MyClass, it prints following output

Inside testIt funtion.
null

however on debugging this, I can see value of cause private variable is set to ValidationException which is expected but while calling getter of that private field returns null.

Jon Skeet
people
quotationmark

The ValidationException you've thrown will be th in your calling code... there's no cause for that ValidationException. The point of getCause() is for one exception to be able to refer to another one as an underlying cause - but there's only one exception in your case.

The fact that you see the private cause variable's value being the ValidationException is entirely in line with how that field is documented (emphasis mine):

The throwable that caused this throwable to get thrown, or null if throwable was not caused by another throwable, or if the causative throwable is unknown. If this field is equal to this throwable itself, it indicates that the cause of this throwable has not yet been initialized.

And that's why getCause() is implemented as:

return (cause==this ? null : cause);

If you want to see the intended chaining in effect, you could create two exceptions, one chained to the other:

throw new ValidationException("Validation Exception..",
    new IllegalArgumentException("Bang!"));

Now calling getCause() on the ValidationException will return the IllegalArgumentException.

You probably just want to change your calling code to log th instead of th.getCause() though.

people

See more on this question at Stackoverflow