-
Notifications
You must be signed in to change notification settings - Fork 3
Description
We currently have a very disjointed way of performing error handling in our FFI methods. We sometimes
return "null" where possible, but we really don't have a sound methodology for handling error conditions.
This is a proposal for how we can explicity encode error handling into the model.
consider a creation function which might fail:
Foo* create_foo(FOOConfig config, Other* other);
It could fail for a number of reasons, e.g.:
- something in the
configis bad / not allowed - the pointer
otheris null or something (e.g. a runtime) has already been destroyed
We can encode all of the possible failures as a special error type. Typically there would only be one such
error type for a library, but we'd design it such that multiple error types can co-exist:
let error = lib
.define_error("error", "ok")? // the name of the error and the ok variant (which must exist)
.add("bad_parameter")?
.add("null_parameter")?
.add("runtime_shutdown")?
.build()?;
In native functions that can fail, we simply declare that the function is fallible:
let function = lib
.define_native_function("..")?
...
.fallible(error)?
.build()?;
Now that this information is part of the model for every function, we can map this in back-end specific ways.
In C, fallible functions will always return the error as an enum and add an out parameter if there is a return type:
error_t create_c(A config, B* pointer, Foo** out);
This is a well-defined pattern that we can use for any function which might be fallible. This will allow C users to check that the error code is "ok" before proceeding.
OO languages can generate an exception type for each error type in a library:
ErrorException {
Error error;
}
Native functions can be wrapped into "exception" functions.
Most of our Java/C# code won't have to change at all except that they'll magically start throwing exceptions instead
of returning null, panicking, or silently failing. All we need is a thin generated layer that checks errors from the FFI
and tosses an exception if this occurs. Since the error information is now on every relevant function/method we can even produce
exception documentation automatically.