Exception Handling
Groovy doesn't enforce checked exceptions. Declaring throws is optional (but useful for Java callers).
org.codehaus.groovy.runtime.StackTraceUtils.sanitize(e) removes Groovy internals from stack traces.
class InsufficientFundsException extends RuntimeException {
BigDecimal shortfall
InsufficientFundsException(String msg, BigDecimal shortfall) { super(msg); this.shortfall = shortfall }
}
def withdraw(balance, amount) {
if (amount > balance) throw new InsufficientFundsException("Insufficient funds", amount - balance)
balance - amount
}
try {
withdraw(100, 150)
} catch (InsufficientFundsException e) {
println "${e.message}: short by ${e.shortfall}"
} catch (IllegalArgumentException | IllegalStateException e) { // multi-catch
println "Bad input"
} catch (e) { // untyped catch = Exception
println "Other: $e"
} finally {
println "Always runs"
}
// try-with-resources (ARM blocks, Groovy 3+), or GDK withCloseable/withReader
try (def reader = new File("data.txt").newReader()) {
println reader.readLine()
}
new File("data.txt").withReader { r -> println r.readLine() } // auto-closes
// assert with the power assert output
def x = 5
assert x * 2 == 11 : "Math is broken"
// Assertion failed: Math is broken. Expression: (x * 2 == 11). Values: x = 5