Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node::get_node unexpected panic when given a path to a non-existent node #1001

Closed
davehadley opened this issue Jan 8, 2023 · 1 comment · Fixed by #1002
Closed

Node::get_node unexpected panic when given a path to a non-existent node #1001

davehadley opened this issue Jan 8, 2023 · 1 comment · Fixed by #1002
Labels
bug c: core Component: core (mod core_types, object, log, init, ...)
Milestone

Comments

@davehadley
Copy link

When I use Node::get_node to retrieve a Node that does not exist, according to the documentation

null is returned and an error is logged. Attempts to access methods on the return value will result in an “Attempt to call on a null instance.”. 

so I expected that null would map to None in rust. Instead get_node panics with the message Unexpected variant type: InvalidNil. This was discussed on Discord and recommended to be reported here.

A short example that reproducers this panic:

use gdnative::prelude::*;

#[derive(NativeClass)]
#[inherit(Node)]
struct ExampleGetNodeThatDoesNotExistPanics {}

impl ExampleGetNodeThatDoesNotExistPanics {
    fn new(_base: &Node) -> Self {
        Self {}
    }
}

#[methods]
impl ExampleGetNodeThatDoesNotExistPanics {

    #[method]
    fn _ready(&mut self, #[base] _base: &Node) {
        godot_print!("ExampleGetNodeThatDoesNotExistPanics _ready about to get_node");
        let _ = _base.get_node("does not exist"); // panics with message: "Unexpected variant type: InvalidNil"
        godot_print!("ExampleGetNodeThatDoesNotExistPanics this line never executes due to panic");
    }
}

fn init(handle: InitHandle) {
    handle.add_class::<ExampleGetNodeThatDoesNotExistPanics>();
}


godot_init!(init);

and the error message and backtrace:

ERROR: (Node not found: "does not exist" (relative to "/root/Scene").)
   at: get_node (scene/main/node.cpp:1465)
thread '<unnamed>' panicked at 'Unexpected variant type: InvalidNil', /home/dave/home/gdnative-get-node-panic-example/target/debug/build/gdnative-bindings-cfa8e4943b33c4de/out/generated.rs:1977:23307
stack backtrace:
   0: rust_begin_unwind
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:575:5
   1: core::panicking::panic_fmt
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/panicking.rs:65:14
   2: core::result::unwrap_failed
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/result.rs:1791:5
   3: core::result::Result<T,E>::expect
             at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/result.rs:1070:23
   4: gdnative_bindings::generated::node::<impl gdnative_bindings::generated::node::private::Node>::get_node
             at /home/dave/home/gdnative-get-node-panic-example/target/debug/build/gdnative-bindings-cfa8e4943b33c4de/out/generated.rs:1977:23209
   5: gdnative_get_node_panic_example::ExampleGetNodeThatDoesNotExistPanics::_ready

A small Godot project reproducing the problem: gdnative-get-node-panic-example.zip

@davehadley davehadley added the bug label Jan 8, 2023
@davehadley
Copy link
Author

In case someone else has run into the same problem, I am documenting here the workarounds suggested on the discord by @chitoyuu and thomastc.

@chitoyuu chitoyuu added this to the v0.11.x milestone Jan 8, 2023
@chitoyuu chitoyuu added the c: core Component: core (mod core_types, object, log, init, ...) label Jan 8, 2023
bors bot added a commit that referenced this issue Jan 8, 2023
1002: Catch null object pointers in Variant::is_nil r=chitoyuu a=chitoyuu

With varcall, Godot sometimes return null objects as Variants with `VariantType::Object` but a null pointer, instead of the usually expected/assumed `VariantType::Nil`. This caused `Option::from_variant` to panic in case of null objects returned by Godot in this way.

Fix #1001

Co-authored-by: Chitose Yuuzaki <chitoyuu@potatoes.gay>
@bors bors bot closed this as completed in 002d5d6 Jan 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug c: core Component: core (mod core_types, object, log, init, ...)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants