Skip to content

Commit fa7c178

Browse files
bors[bot]Bromeon
andauthored
Merge #960
960: Improve panic messages in init/terminate callbacks r=Bromeon a=Bromeon Fixes #959. Co-authored-by: Jan Haller <[email protected]>
2 parents 8a82bda + 6f5241d commit fa7c178

File tree

5 files changed

+34
-19
lines changed

5 files changed

+34
-19
lines changed

gdnative-core/src/export/method.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,11 +876,12 @@ unsafe extern "C" fn method_wrapper<C: NativeClass, F: Method<C>>(
876876
});
877877

878878
result
879-
.unwrap_or_else(|_| {
879+
.unwrap_or_else(|e| {
880880
crate::log::error(
881881
F::site().unwrap_or_default(),
882882
"gdnative-core: method panicked (check stderr for output)",
883883
);
884+
crate::private::print_panic_error(e);
884885
Variant::nil()
885886
})
886887
.leak()

gdnative-core/src/export/property/accessor.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,9 @@ where
252252
}
253253
});
254254

255-
result.unwrap_or_else(|_| {
255+
result.unwrap_or_else(|e| {
256256
godot_error!("gdnative-core: property setter panicked (check stderr for output)");
257+
crate::private::print_panic_error(e);
257258
})
258259
}
259260
set.set_func = Some(invoke::<SelfArg, C, F, T>);
@@ -324,8 +325,9 @@ where
324325
}
325326
});
326327

327-
result.unwrap_or_else(|_| {
328+
result.unwrap_or_else(|e| {
328329
godot_error!("gdnative-core: property getter panicked (check stderr for output)");
330+
crate::private::print_panic_error(e);
329331
Variant::nil().leak()
330332
})
331333
}

gdnative-core/src/init/init_handle.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,12 @@ impl InitHandle {
123123
})
124124
})) {
125125
Ok(val) => val,
126-
Err(_) => {
126+
Err(e) => {
127127
godot_error!(
128128
"gdnative-core: error constructing {}: constructor panicked",
129129
class_registry::class_name_or_default::<C>(),
130130
);
131+
crate::private::print_panic_error(e);
131132
return ptr::null_mut();
132133
}
133134
};

gdnative-core/src/init/macros.rs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,9 @@ macro_rules! godot_nativescript_init {
5656
}
5757
}
5858

59-
let __result = ::std::panic::catch_unwind(|| {
59+
$crate::private::report_panics("nativescript_init", || {
6060
$callback($crate::init::InitHandle::new(handle));
6161
});
62-
63-
if __result.is_err() {
64-
$crate::godot_error!("gdnative-core: nativescript_init callback panicked");
65-
}
6662
}
6763
};
6864
}
@@ -104,13 +100,10 @@ macro_rules! godot_gdnative_init {
104100
return;
105101
}
106102

107-
let __result = ::std::panic::catch_unwind(|| {
108-
let callback_options = $crate::init::InitializeInfo::new(options);
109-
$callback(&callback_options)
103+
$crate::private::report_panics("gdnative_init", || {
104+
let init_info = $crate::init::InitializeInfo::new(options);
105+
$callback(&init_info)
110106
});
111-
if __result.is_err() {
112-
$crate::godot_error!("gdnative-core: gdnative_init callback panicked");
113-
}
114107
}
115108
};
116109
}
@@ -152,13 +145,10 @@ macro_rules! godot_gdnative_terminate {
152145
return;
153146
}
154147

155-
let __result = ::std::panic::catch_unwind(|| {
148+
$crate::private::report_panics("gdnative_terminate", || {
156149
let term_info = $crate::init::TerminateInfo::new(options);
157150
$callback(&term_info)
158151
});
159-
if __result.is_err() {
160-
$crate::godot_error!("gdnative-core: nativescript_init callback panicked");
161-
}
162152

163153
$crate::private::cleanup_internal_state();
164154
}

gdnative-core/src/private.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::ffi::CString;
2+
use std::panic::{catch_unwind, UnwindSafe};
23

34
use crate::sys;
45

@@ -181,6 +182,26 @@ unsafe fn report_init_error(
181182
}
182183
}
183184

185+
#[inline]
186+
pub fn report_panics(context: &str, callback: impl FnOnce() + UnwindSafe) {
187+
let __result = catch_unwind(callback);
188+
189+
if let Err(e) = __result {
190+
godot_error!("gdnative-core: {} callback panicked", context);
191+
print_panic_error(e);
192+
}
193+
}
194+
195+
pub(crate) fn print_panic_error(err: Box<dyn std::any::Any + Send>) {
196+
if let Some(s) = err.downcast_ref::<String>() {
197+
godot_error!("Panic message: {}", s);
198+
} else if let Some(s) = err.downcast_ref::<&'static str>() {
199+
godot_error!("Panic message: {}", s);
200+
} else {
201+
godot_error!("Panic message unknown, type {:?}", err.type_id());
202+
}
203+
}
204+
184205
pub mod godot_object {
185206
pub trait Sealed {}
186207
}

0 commit comments

Comments
 (0)