I'm writing a testMethod for a custom Exception class.
As part of the testMethod I want to deliberately throw another exception to become the inner cause of my custom exception.
E.g.
public class CustomException extends Exception {
public Id opportunityId {
get;
private set;
}
public CustomException(Id exceptionOpportuntiyId, string message, Exception innerException) {
this.opportunityId = exceptionOpportuntiyId;
this.setMessage(message);
this.initCause(innerException);
}
}
And the corresponding testMethod:
private static testMethod void customExceptionTest() {
Id opportuntiyId = '006000000000000';
try {
Savepoint sp = Database.setSavepoint();
try {
integer foo = null;
// Intentional NullPointerException
foo = foo + 1;
System.assert(false, 'Null Exception Expected');
} catch (NullPointerException ex) {
Database.rollback(sp);
throw new CustomException(opportuntiyId, 'customExceptionTest', ex);
}
System.assert(false, 'CustomException Expected');
} catch (CustomException saveEx) {
System.assertEquals(opportuntiyId, saveEx.opportunityId);
System.assertEquals('customExceptionTest', saveEx.getMessage());
}
}
Oddly, the assertion in the inner try block is causing the test method to fail. The line foo = foo + 1
executed without throwing an exception!
This seemed odd, so I tried simplifying.
The following produces the expected NullPointerException when run as anonymous apex:
integer foo = null;
foo = foo + 1;
12:38:48:016 FATAL_ERROR System.NullPointerException: Attempt to de-reference a null object
The wrapping the same code in a try/catch block:
try {
integer foo = null;
foo = foo + 1;
System.debug('foo: ' + foo);
} catch (NullPointerException ex) {
System.debug('Exception');
}
12:42:28:013 USER_DEBUG [6]|DEBUG|foo: null
The expected NullPointerException didn't occur. Instead foo
is null!
I've raised with support (Case #08416231), but is anyone else aware of this or can confirm it is occurring for them as well?
Ideally I'd like a known issue reference or existing case number.
Best Answer
I get the same and also agree it looks like an Apex runtime bug. Perhaps relating to scope, as moving the variable declaration and init out of the try scope works...