Why this matters
Prevents leaks and turns low-level failures into meaningful responses.
Catch and map DB exceptions (e.g., SQLIntegrityConstraintViolationException) to domain results; always close resources with use { }.
Prevents leaks and turns low-level failures into meaningful responses.
Side-by-side examples engineers can pattern-match during review.
val rs = stmt.executeQuery(sql)
// no try/catch, no closetry {
dataSource.connection.use { c ->
c.prepareStatement(sql).use { ps -> ps.executeUpdate() }
}
} catch (e: SQLException) {
logger.error("db error", mapOf("sql" to sql, "err" to e))
return Result.failure(e)
}stmt.executeQuery(q) // uncheckedtry { ds.connection.use { /*...*/ } } catch (e: SQLException) { /* map */ }From the same buckets as this rule.
Review SQL/database migrations for operations that can lock large tables or cause downtime. Examples: creating indexes without CONCURRENTLY (Postgres), ALTER COLUMN TYPE on big tables, adding NOT NULL without backfill, long-running updates without batching. Require an online migration strategy (CONCURRENTLY, backfill in batches, dual-write/expand-contract) and a rollback plan.