A statically typed, general-purpose programming language, crafted for simplicity and performance.
"Trust the programmer" - corx
This is one of the most basic error handling approaches. It handles division by zero by printing an error message ("division by zero") and returning a default value (-1.0). However, this method has limitations. Specifically, if you need to capture both the output and the error together, it won't suffice, as the error is only printed and not passed back as part of the return value.
float divide(int x, int y) {
if (y == 0) {
print("division by zero");
return -1.0;
}
return x / y;
}
exit
FunctionThe exit
function can be useful in certain contexts, but it might not always be the desired
behavior. It triggers the program to exit, which may not be appropriate in every situation.
float divide(int x, int y) {
if (y == 0) exit("division by zero.");
return x / y;
}
Note: exit
function causes stack unwinding and prints the full stack trace.
exit
function variations:
exit(int); # error number
exit(error); # error object
exit(string); # error string
exit(int, string); # error number, error string
throw
and catch
A structured built-in error handling mechanism. Errors are raised using
throw error(num,str)
and caught with catch
, where the error
object
provides detailed context for handling the issue.
This mechanism operates within the current context. A throw
and its corresponding
catch
must be separated by no more than one level of the call stack. Errors must be caught and
handled within the immediate calling context. Each calling context can independently define its own
throw
and catch
. If multiple errors are thrown within the same scope, only the
most recent error will be caught.
The example below demonstrates a single context:
float divide(int x, int y) {
if (y == 0) throw error(1, "division by zero");
return x / y;
}
float res = divide(6, 0) catch { # catches context based last exception
print(error->num, error->str); # error object available within context
}
throw
, catch
with async
, wait
The async
keyword initiates an operation, and
wait
pauses execution until it completes. Errors are caught within the same scope
catch
, ensuring consistent handling of both sync and async errors.
wait float rem = async fetch("resource") catch {
exit(error); # passed error object
}