GitHub - bursauxa/play-sql-timeout-repro: Repro scenario for misleading exception bubbling in Play SQL · GitHub
Skip to content

About

Repro scenario for misleading exception bubbling in Play SQL

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

Database.withTransaction hides the error that broke the transaction

play.api.db.Database.withTransaction has a problem when a JDBC connection dies mid-transaction: it reports java.sql.SQLException: Connection is closed, and not the error that actually killed it. The real cause never reaches the caller, and it never reaches the application logs either. Both overloads are affected: the one taking an isolation level, and the one without.

The transaction itself is handled correctly, and every test here checks that nothing was committed: the server rolls it back as soon as the connection goes away, whichever end of the socket failed. What is lost is only the diagnosis, and it disappears precisely when a database starts misbehaving, in other words, at the very moment where a clear error message would be most valuable.

Reproduced with Play 3.0.11, MariaDB 11.4 and the MariaDB Connector/J 3.5.10.

Running it

Requires a Docker-compatible runtime (the test starts a MariaDB container through Testcontainers).

sbt test

Output at the time of issue report:

[info] Database.withTransaction
[info] - should commit the inserted rows
[info] - should report the cause, when the server drops the session *** FAILED ***
[info]   java.sql.SQLException: Connection is closed was not an instance of java.sql.SQLNonTransientConnectionException
[info] - should report the cause, when the network timeout expires *** FAILED ***
[info]   java.sql.SQLException: Connection is closed was not an instance of java.sql.SQLNonTransientConnectionException
[info] Database.withTransaction, with an isolation level
[info] - should commit the inserted rows
[info] - should report the cause, when the server drops the session *** FAILED ***
[info]   java.sql.SQLException: Connection is closed was not an instance of java.sql.SQLNonTransientConnectionException
[info] - should report the cause, when the network timeout expires *** FAILED ***
[info]   java.sql.SQLException: Connection is closed was not an instance of java.sql.SQLNonTransientConnectionException
[info] Tests: succeeded 2, failed 4, canceled 0, ignored 0, pending 0

The exception the caller should have received is SQLNonTransientConnectionException: (conn=4) Socket error, in one case, and SQLNonTransientConnectionException: (conn=9) Socket timout error in the other.

Verifying a fix

The tests assert the behaviour that is expected of withTransaction, not the behaviour it has today, so a fix turns the whole suite green without a single change to this repository. All six must pass, since a fix is only complete once both overloads report the cause. To try one out, publish your Play build locally, then point this project at it:

# in your playframework checkout
sbt publishLocal                    # the whole build, play-jdbc alone leaves its own dependencies unresolvable
sbt "show Play-JDBC/version"        # the version to use below, e.g. 3.1.0-M10-SNAPSHOT on main

# here
sbt -Dplay.version=<that version> test

About

Repro scenario for misleading exception bubbling in Play SQL

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages