Errors in CLIPS

Our error handling example demonstrates how Java handles exceptions, which is the primary mechanism for error handling in the language. This contrasts with Go’s approach of using explicit return values for errors.

import java.util.Arrays;

public class ErrorHandling {

    // In Java, we use exceptions instead of returning error values.
    // This method throws an exception instead of returning an error.
    public static int f(int arg) throws Exception {
        if (arg == 42) {
            // We throw an exception instead of returning an error.
            throw new Exception("can't work with 42");
        }
        // No error, just return the result.
        return arg + 3;
    }

    // Custom exceptions can be used to represent specific error conditions.
    static class OutOfTeaException extends Exception {
        public OutOfTeaException(String message) {
            super(message);
        }
    }

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

    public static void makeTea(int arg) throws OutOfTeaException, PowerException {
        if (arg == 2) {
            throw new OutOfTeaException("no more tea available");
        } else if (arg == 4) {
            // In Java, we can wrap exceptions by passing them to the constructor
            // of another exception.
            throw new PowerException("making tea: can't boil water");
        }
    }

    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 (Exception 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 (OutOfTeaException e) {
                System.out.println("We should buy new tea!");
            } catch (PowerException e) {
                System.out.println("Now it is dark.");
            } catch (Exception e) {
                System.out.printf("unknown error: %s\n", e.getMessage());
            }
        }
    }
}

In Java, we use exceptions for error handling. Here’s how the concepts translate:

  1. Instead of returning error values, Java methods throw exceptions.

  2. The try-catch block is used to handle exceptions, similar to checking returned errors in Go.

  3. Custom exceptions can be created by extending the Exception class, which is similar to creating custom error types in Go.

  4. Java doesn’t have the concept of “sentinel errors”. Instead, we use custom exception types to represent specific error conditions.

  5. Exception wrapping in Java is done by passing one exception to another’s constructor, which is conceptually similar to error wrapping in Go.

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

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 example demonstrates how Java’s exception handling can be used to achieve similar error handling patterns as in Go, albeit with different syntax and conventions.