Errors from godot registration functions are not detected
I stumbled upon this here: https://github.com/godot-rust/gdext/pull/1019#issuecomment-2603887272
See also: https://github.com/godotengine/godot/issues/101870
The issue is that in godot, classdb_register_extension_class_method returns void.
If an error occurs, it just prints an error and returns:
https://github.com/godotengine/godot/blob/1b7b009674e05b566be11a5377b935f5d3d6c0ee/core/object/class_db.cpp#L1879-L1882
if (type->method_map.has(p_method->get_name())) {
// overloading not supported
ERR_FAIL_MSG(vformat("Method already bound '%s::%s'.", p_class, p_method->get_name()));
}
The macro ERR_FAIL_MSG ultimately calls _err_print_error
which prints to stderr and calls all handlers registered in error_handler_list.
At the least for debug / CI, it would be great to register a handler, and fail CI if an error occurs.
Note: godot seems to do something similar here: https://github.com/godotengine/godot/blob/1b7b009674e05b566be11a5377b935f5d3d6c0ee/tests/test_tools.h#L39
My Rust <-> Cpp interop knowledge is limited, but I believe we can't just call that function, without it being explicitly exposed, right? I added a feature request here: https://github.com/godotengine/godot-proposals/issues/11618
You're right, the only way to interact with Godot is through gdextension_interface.h.
We additionally have extension_api.json, but this contains just data, no functions.
And indeed, classdb_register_extension_class_method does not return a status code, and I'm not aware of an API to fetch previous errors, either.
An alternative to having errors on Godot side would be:
- validate invariants (symbol not yet registered) beforehand, through
ClassDBAPI - maintain runtime state on godot-rust side and check against that
Both work for simple cases, but may fall apart for more complex validations, and would require Rust to keep up with the exact logic that Godot provides.