ZetCode

Groovy Exceptions

last modified October 15, 2026

Exceptions signal errors that the normal flow of a program cannot handle. Groovy uses the same exception classes as Java, and it simplifies the syntax by not requiring you to declare checked exceptions. This tutorial shows how to catch, throw, and define exceptions in Groovy.

try, catch, and finally

A try block contains code that may fail. Each catch block handles one exception type, and the optional finally block runs whether or not an exception occurred.

TryCatchFinally.groovy
def text = "abc"

try {
    def number = text.toInteger()
    println "Number: $number"
} catch (NumberFormatException e) {
    println "Invalid input: ${e.message}"
} finally {
    println "Parsing finished"
}

"abc".toInteger() throws a NumberFormatException. The catch block reports the problem, and the finally block runs afterwards. Use finally for cleanup that must always happen.

Throwing Exceptions

Use throw to signal an error from your own code. Groovy methods can return values directly, so a method that validates input often either returns a result or throws.

ThrowException.groovy
def withdraw(double balance, double amount) {
    if (amount <= 0) {
        throw new IllegalArgumentException("Amount must be positive")
    }
    if (amount > balance) {
        throw new IllegalStateException("Insufficient funds: $balance < $amount")
    }
    return balance - amount
}

try {
    println withdraw(100, 30)
    println withdraw(100, 500)
} catch (IllegalStateException e) {
    println "Error: ${e.message}"
}

The first call returns 70.0, because the arguments are double values. The second call throws an IllegalStateException, which the caller catches and reports. Using standard exception types such as IllegalArgumentException makes the intent clear to other developers.

Custom Exceptions

Create your own exception class by extending Exception or RuntimeException. Custom types let callers catch one specific error without catching unrelated failures.

CustomException.groovy
class InvalidAgeException extends Exception {
    InvalidAgeException(String message) {
        super(message)
    }
}

def checkAge(int age) {
    if (age < 0) {
        throw new InvalidAgeException("Age cannot be negative: $age")
    }
    return age
}

try {
    checkAge(-5)
} catch (InvalidAgeException e) {
    println "Custom error: ${e.message}"
}

InvalidAgeException carries a message through its constructor. The caller can catch it specifically, which is more precise than catching Exception in general.

Multiple Catch Blocks and the Exception Hierarchy

Catch blocks are checked in order, so list the more specific types first. A catch clause for Exception acts as a fallback for anything not handled above it.

CatchOrder.groovy
def readNumber(String text) {
    try {
        return text.toInteger()
    } catch (NumberFormatException e) {
        println "Not a number"
        return null
    } catch (Exception e) {
        println "Unexpected: ${e.class.simpleName}"
        return null
    }
}

println readNumber("42")
println readNumber("x")
println readNumber(null)

Passing null to toInteger() throws a NullPointerException, which is not a NumberFormatException, so the fallback Exception clause handles it. Putting the general clause first would hide the more specific handler.

Closing Resources Safely

Groovy's withReader, withWriter, and withInputStream methods close the resource automatically, even when an exception is thrown inside the closure. This replaces most explicit finally blocks used for cleanup.

ResourceClosing.groovy
def file = new File("notes.txt")
file.text = "first line\nsecond line"

try {
    file.withReader { reader ->
        println reader.readLine()
        throw new RuntimeException("Simulated failure")
    }
} catch (RuntimeException e) {
    println "Caught: ${e.message}"
} finally {
    file.delete()
}

The reader is closed before the exception reaches the catch block, even though the closure threw. The finally block here removes the temporary file used for the demonstration.

Best Practices

Source

Groovy Semantics Documentation | Java Exception API

Groovy exception handling follows Java's model with a lighter syntax. Catching specific types, throwing meaningful messages, and relying on closure-based resource handling produce code that is short and easy to maintain.

Author

My name is Jan Bodnar, and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Groovy tutorials.