How could one convert the `try-with-resources` con...
# announcements
j
How could one convert the
try-with-resources
construct in Java to Kotlin, regarding handling exceptions?
Copy code
// Java
DataSource ds = createDataSource();
try (Connection connection = ds.getConnection()) {
    // ...
    // just throw exception for simulation
    throw new IllegalStateException()
    // ...
} catch (SQLException e) {
    e.printStackTrace()
}
I’ve tried to use the
use
function like this:
Copy code
// Kotlin
val ds: DataSource = createDataSource()
try {
    dataSource.connection.use { connection ->
        // just throw exception for simulation
        throw IllegalStateException()
    }
} catch (e: SQLException) {
    e.printStackTrace()
}
But
SQLException
is not caught, instead, only
IllegalStateException
could be caught. How could one catch a
SQLException
thrown from
java.sql.Connection.getConnection()
gracefully using Kotlin, while, if possible, utilizing the
use
function to close the connection?
a
can you move the catch inside the use?
j
No, it also wouldn’t work.
l
I find it pretty normal that you get what you throw and not another exception. If you want to test
SQLException
, then throw a
SQLException
, not something else.
j
@JP to elaborate on Louis’s comment, your code works fine. Here’s a complete example testing the right exception:
Copy code
import java.sql.SQLException

class Connection : AutoCloseable {
    override fun close() {
    }
}

class DataSource {
    val connection: Connection
        get() {
            throw SQLException("Ooops")
        }
}

fun createDataSource() = DataSource()

fun main() {
    val ds: DataSource = createDataSource()
    try {
        ds.connection.use { connection ->
            // just throw exception for simulation
            throw IllegalStateException()
        }
    } catch (e: SQLException) {
        println("Caught SQLException")
        e.printStackTrace()
    }
}
j
Thank you for the comments. I think I now have a better understanding than before. @jbnizet Is it frequently done in practice then, to wrap
try/catch
block outside the
use
block, and also use another
try/catch
block inside the
use
block for example, in case of executing rollback before the
AutoClosable
resource is closed by the
use
block? Or is there a more concise way to handle it?