#load "std/error.bl"
There is no support for exceptions of any kind in BL, however, there are a few features in the language helping with error handling such as defer and multiple return values. In general, every possibly failing function should return an error state in case of failure containing an error code and some message describing the problem. This style is widely adopted by the standard library and may be used in the user code as well.
The error state is represented by the following data structure:
_Error :: struct {
msg: string_view;
code: s32;
}
Error :: *_Error;
div :: fn (a: s32, b: s32) (s32, Error) {
if b == 0 {
// Return error with message.
return 0, error("Divide by zero '%/%'!", a, b);
}
// Return result and OK state.
return a / b, OK;
}
main :: fn () s32 {
loop i := -5; i <= 5; i += 1 {
result, error :: div(10, i);
if error {
print("Error: %.\n", error);
} else {
print("Result is %.\n", result);
}
}
return 0;
}
As already mentioned, the defer statement may be helpful in situations where we need to free some memory or do any kind of resource cleanup before the failing function returns the error state.
Error :: *_Error
File: error.bl
OK : Error = null
No error.
File: error.bl
is_error :: fn (err: Error, code: s32) bool #inline
Check whether err
is representing error code
. Returns false
when err
is null
.
File: error.bl
error :: fn {
impl_error1;
impl_error2;
impl_error3;
}
Overloaded function setting up error state. Error state is global variable holding Error
instance, error
function sets desired values and return pointer to this global. That means
the Error
must be handled immediately after it's returned from failing function since every
Error
state points to the same memory.
Error creating does not require any HEAP memory alocations.
Overloads:
fn (code: s32) Error #inline
fn (format: string, args: ...) Error #inline
fn (code: s32, format: string, args: ...) Error #inline
Sets error state with code
and formatted message.
File: error.bl