After-completion callback not triggered for custom Throwable subclass [SPR-14329] #18901
Labels
status: backported
An issue that has been backported to maintenance branches
type: bug
A general bug
Milestone
Ben Heilers opened SPR-14329 and commented
Our team observed this, although I admit it is probably a rare situation.
To summarize, the JDBC connection is never released if:
I reproduced it with just small changes to the project at https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-data-jpa.
First, I changed the line in the controller method from "Bath" to "Foo", below:
This causes getCity() to return null, so the method throws an NPE.
So far, everything is okay, the exception is caught here, and the JDBC connection is still released within the call to triggerAfterCompletion().
But we really wanted a custom response HTTP status of 400 instead of 500, so we added:
Now the status is 500, but we still wanted some special logic in that exception handler for adding a log message.
Eventually, we observed now that in some scenarios that handling logic ends up throwing an second exception while trying to handle the exception thrown in the controller method.
This isn't so bad, because secondary exceptions thrown during exception handling are caught and handled here.
But we observed that the second exception is a custom class, that had an override of some of the methods in Throwable ... and those overrides in turn threw a third exception.
This also wouldn't be so bad by itself, because there is logic here to still end up unreleasing the JDBC connection in that scenario, as long as the exception sublcasses either Exception or Error.
Unfortunately, we found in our case this custom exception class was directly extending Throwable.
This means the JDBC connection is not released.
The below is a bit contrived, but it proves the point:
While I admit this is probably a rare edge case, this is actually a security vulnerability, since unreleased connections can be used as an attack vector. And there is nothing inapprorpiate about subclassing Throwable, or overriding methods like getMessage() to do custom logic there.
NOTE: if you are on spring 4.3, the logging level is debug, where it used to be error, so this whole issue is only reproducible if you also add the following to resources/application.properties:
Affects: 4.2.6, 4.3 RC2
Issue Links:
@ExceptionHandler
cannot handler java.lang.Error despite the annotation accept ? extends ThrowableBackported to: 4.2.7
The text was updated successfully, but these errors were encountered: