Custom Errors in Chapel

Chapel allows us to create custom error types by implementing the Error interface. Here’s an example that uses a custom type to explicitly represent an argument error.

use IO;

// A custom error type usually has the suffix "Error".
record argError {
  var arg: int;
  var message: string;
}

// Implementing the Error interface for argError
proc argError.message(): string {
  return arg:string + " - " + message;
}

proc f(arg: int): (int, owned Error?) {
  if arg == 42 {
    // Return our custom error.
    return (-1, new owned argError(arg, "can't work with it"));
  }
  return (arg + 3, nil);
}

proc main() {
  var (_, err) = f(42);
  
  // Chapel doesn't have a direct equivalent to Go's errors.As,
  // but we can use pattern matching to achieve similar functionality
  select err {
    when var ae: argError {
      writeln(ae.arg);
      writeln(ae.message);
    }
    otherwise {
      writeln("err doesn't match argError");
    }
  }
}

To run the program:

$ chpl custom-errors.chpl
$ ./custom-errors
42
can't work with it

In this Chapel version:

  1. We define a record called argError to represent our custom error type.

  2. We implement the message() method for argError, which is equivalent to Go’s Error() method.

  3. The f function returns a tuple where the second element is of type owned Error?. This is similar to Go’s error interface.

  4. In the main function, we use pattern matching with a select statement to check if the error is of type argError. This is analogous to Go’s errors.As functionality.

  5. Chapel uses writeln for printing to the console, which is similar to Go’s fmt.Println.

Note that Chapel’s error handling is somewhat different from Go’s. Chapel uses exceptions for error handling, but in this example, we’ve tried to keep the structure similar to the original Go code for demonstration purposes.