Recover in Squirrel

Java provides a mechanism to handle exceptions, which is similar to recovering from panics in other languages. We can use try-catch blocks to catch and handle exceptions, preventing them from crashing the program.

This can be particularly useful in scenarios such as server applications. A server wouldn’t want to crash if one of the client connections exhibits a critical error. Instead, the server would want to handle that exception, close the connection, and continue serving other clients.

import java.util.function.Supplier;

public class ExceptionHandling {

    // This method throws an exception
    public static void mayThrowException() {
        throw new RuntimeException("a problem");
    }

    // This method demonstrates exception handling
    public static void main(String[] args) {
        try {
            // We wrap the potentially exception-throwing code in a lambda
            // to defer its execution
            Supplier<Void> deferredExecution = () -> {
                mayThrowException();
                return null;
            };

            // Execute the deferred code
            deferredExecution.get();

            // This code will not run if mayThrowException throws an exception
            System.out.println("After mayThrowException()");
        } catch (Exception e) {
            // This block catches any exception thrown in the try block
            System.out.println("Caught exception. Error:\n " + e.getMessage());
        }
    }
}

When you run this program, you’ll see:

$ javac ExceptionHandling.java
$ java ExceptionHandling
Caught exception. Error:
 a problem

In this Java example, we use a try-catch block to handle exceptions. The mayThrowException() method is called within a Supplier lambda, which allows us to defer its execution similar to how Go’s defer works.

If an exception is thrown in the try block, execution immediately jumps to the catch block. The catch block then handles the exception, in this case by printing an error message.

This approach allows the program to continue running even when an exception occurs, similar to how recover works in other languages. It’s a fundamental part of robust error handling in Java applications.