Errors in D Programming Language
import std.stdio;
import std.exception;
// By convention, errors are often returned as the last value
// and have type Exception or Error.
int f(int arg) {
if (arg == 42) {
// new Exception constructs a basic Exception
// with the given error message.
throw new Exception("can't work with 42");
}
// A function that doesn't throw an exception
// indicates that there was no error.
return arg + 3;
}
// A custom exception is similar to a sentinel error in Go
class OutOfTeaException : Exception {
this(string msg, string file = __FILE__, size_t line = __LINE__) {
super(msg, file, line);
}
}
class PowerException : Exception {
this(string msg, string file = __FILE__, size_t line = __LINE__) {
super(msg, file, line);
}
}
void makeTea(int arg) {
if (arg == 2) {
throw new OutOfTeaException("no more tea available");
} else if (arg == 4) {
// In D, we can't directly wrap exceptions like in Go,
// but we can create a new exception with additional context
throw new Exception("making tea: " ~ new PowerException("can't boil water").msg);
}
}
void main() {
import std.range : only;
foreach (i; only(7, 42)) {
try {
int r = f(i);
writeln("f worked: ", r);
} catch (Exception e) {
writeln("f failed: ", e.msg);
}
}
foreach (i; 0 .. 5) {
try {
makeTea(i);
writeln("Tea is ready!");
} catch (OutOfTeaException e) {
writeln("We should buy new tea!");
} catch (PowerException e) {
writeln("Now it is dark.");
} catch (Exception e) {
if (cast(PowerException) e) {
writeln("Now it is dark.");
} else {
writefln("unknown error: %s", e.msg);
}
}
}
}
This D code demonstrates error handling using exceptions, which is the idiomatic way to handle errors in D. Here are some key points about the translation:
D uses exceptions for error handling, unlike Go’s explicit error return values.
We define custom exceptions (
OutOfTeaException
andPowerException
) to represent specific error conditions.Instead of returning errors, we throw exceptions when an error occurs.
The
try
-catch
blocks are used to handle exceptions, similar to how Go uses if-else blocks to check for errors.D doesn’t have a direct equivalent to Go’s error wrapping with
fmt.Errorf
and%w
. Instead, we create a new exception with additional context.To check for specific types of exceptions (similar to
errors.Is
in Go), we usecatch
clauses for specific exception types orcast
within a generalcatch
clause.
To run this program, save it as errors.d
and use the D compiler:
$ dmd errors.d
$ ./errors
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 D handles errors using exceptions, providing similar functionality to Go’s error handling but in a way that’s idiomatic to D.