Errors in Chapel
use Error;
use IO;
// By convention, errors are returned as the last value.
proc f(arg: int): (int, Error) {
if arg == 42 {
// We can create a new error with a message.
return (-1, new Error("can't work with 42"));
}
// A nil value in the error position indicates that
// there was no error.
return (arg + 3, nil);
}
// Sentinel errors are predefined error objects used to
// signify specific error conditions.
var ErrOutOfTea = new Error("no more tea available");
var ErrPower = new Error("can't boil water");
proc makeTea(arg: int): Error {
if arg == 2 {
return ErrOutOfTea;
} else if arg == 4 {
// We can wrap errors to add context. In Chapel, we can
// create a new error that includes the previous error's message.
return new Error("making tea: " + ErrPower.message());
}
return nil;
}
proc main() {
for i in [7, 42] {
// It's common to use an inline error check.
var (r, e) = f(i);
if e != nil {
writeln("f failed: ", e.message());
} else {
writeln("f worked: ", r);
}
}
for i in 0..4 {
var err = makeTea(i);
if err != nil {
// In Chapel, we don't have a built-in way to check if an error
// is a specific predefined error. Instead, we can compare messages.
if err.message() == ErrOutOfTea.message() {
writeln("We should buy new tea!");
} else if err.message().startsWith("making tea: " + ErrPower.message()) {
writeln("Now it is dark.");
} else {
writeln("unknown error: ", err.message());
}
continue;
}
writeln("Tea is ready!");
}
}
In this Chapel translation:
We use the
Error
module for error handling.Functions that can return errors have an
Error
type as their last return value.We create errors using the
new Error()
constructor.Sentinel errors are created as predefined
Error
objects.Error wrapping is simulated by creating a new error with a message that includes the original error’s message.
Since Chapel doesn’t have a built-in way to check if an error is a specific predefined error (like Go’s
errors.Is
), we compare error messages instead.The
nil
value is used to indicate no error, similar to Go.We use Chapel’s
writeln
function for output instead offmt.Println
.
This translation preserves the error handling concepts from the original Go code, adapting them to Chapel’s error handling mechanisms. The overall structure and flow of the program remain similar, demonstrating error creation, checking, and handling in Chapel.