Errors in Karel

Our first example demonstrates error handling in Java. Unlike Go, Java uses exceptions for error handling, which is a different approach but serves a similar purpose.

import java.util.Arrays;

class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

class NoMoreTeaException extends Exception {
    public NoMoreTeaException() {
        super("no more tea available");
    }
}

class CantBoilWaterException extends Exception {
    public CantBoilWaterException() {
        super("can't boil water");
    }
}

public class ErrorHandling {
    public static int f(int arg) throws CustomException {
        if (arg == 42) {
            throw new CustomException("can't work with 42");
        }
        return arg + 3;
    }

    public static void makeTea(int arg) throws NoMoreTeaException, CantBoilWaterException {
        if (arg == 2) {
            throw new NoMoreTeaException();
        } else if (arg == 4) {
            throw new CantBoilWaterException();
        }
    }

    public static void main(String[] args) {
        for (int i : Arrays.asList(7, 42)) {
            try {
                int r = f(i);
                System.out.println("f worked: " + r);
            } catch (CustomException e) {
                System.out.println("f failed: " + e.getMessage());
            }
        }

        for (int i = 0; i < 5; i++) {
            try {
                makeTea(i);
                System.out.println("Tea is ready!");
            } catch (NoMoreTeaException e) {
                System.out.println("We should buy new tea!");
            } catch (CantBoilWaterException e) {
                System.out.println("Now it is dark.");
            } catch (Exception e) {
                System.out.println("unknown error: " + e.getMessage());
            }
        }
    }
}

In Java, we use exceptions to handle errors. This is different from Go’s approach of returning error values, but it serves a similar purpose.

  1. We define custom exceptions by extending the Exception class.

  2. Methods that can throw exceptions declare this using the throws keyword.

  3. Instead of returning multiple values (result and error), Java methods throw exceptions when an error occurs.

  4. We use try-catch blocks to handle exceptions. This is similar to checking for non-nil errors in Go.

  5. Java doesn’t have the concept of “wrapping” errors like Go does with fmt.Errorf. Instead, we can create custom exceptions that contain other exceptions (not shown in this example).

  6. Java’s exception handling is more similar to Go’s panic and recover than to Go’s error handling. However, it’s used much more commonly in Java than panic is in Go.

  7. Java doesn’t have sentinel errors. Instead, we use specific exception types to indicate different error conditions.

When you run this program, you should see output similar to:

f worked: 10
f failed: can't work with 42
Tea is ready!
Tea is ready!
We should buy new tea!
Tea is ready!
Now it is dark.

This demonstrates how Java handles different error conditions using exceptions, which is conceptually similar to Go’s error handling but with a different syntax and approach.