Skip to content

Commit

Permalink
Merge pull request #926 from 0x53A/dev
Browse files Browse the repository at this point in the history
in debug, include location information in error message on panic
  • Loading branch information
Bromeon authored Nov 5, 2024
2 parents 387bd81 + 6eaae57 commit 3722014
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 14 deletions.
34 changes: 23 additions & 11 deletions godot-core/src/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,27 +387,39 @@ where
// Handle panic info only in Debug mode.
#[cfg(debug_assertions)]
{
let guard = info.lock().unwrap();
let info = guard.as_ref().expect("no panic info available");
let msg = extract_panic_message(err);
let mut msg = format_panic_message(msg);

// Try to add location information.
if let Ok(guard) = info.lock() {
if let Some(info) = guard.as_ref() {
msg = format!("{}\n at {}:{}", msg, info.file, info.line);
}
}

if print {
godot_error!(
"Rust function panicked at {}:{}.\n Context: {}",
info.file,
info.line,
"Rust function panicked: {}\n Context: {}",
msg,
error_context()
);
//eprintln!("Backtrace:\n{}", info.backtrace);
}

Err(msg)
}

let msg = extract_panic_message(err);
let msg = format_panic_message(msg);
#[cfg(not(debug_assertions))]
{
let msg = extract_panic_message(err);
let msg = format_panic_message(msg);

if print {
godot_error!("{msg}");
}

if print {
godot_error!("{msg}");
Err(msg)
}

Err(msg)
}
}
}
Expand Down
23 changes: 20 additions & 3 deletions itest/rust/src/object_tests/dynamic_call_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,30 @@ fn dynamic_call_with_panic() {

assert_eq!(call_error.class_name(), Some("Object"));
assert_eq!(call_error.method_name(), "call");
assert_eq!(
call_error.to_string(),

let appendix = if cfg!(debug_assertions) {
let mut path = "itest/rust/src/object_tests/object_test.rs".to_string();

if cfg!(target_os = "windows") {
path = path.replace('/', "\\")
}

// Obtain line number dynamically, avoids tedious maintenance on code reorganization.
let line = ObjPayload::get_panic_line();

format!("\n at {path}:{line}")
} else {
String::new()
};

let expected_error_message = format!(
"godot-rust function call failed: Object::call(&\"do_panic\")\
\n Source: ObjPayload::do_panic()\
\n Reason: [panic] do_panic exploded"
\n Reason: [panic] do_panic exploded{appendix}"
);

assert_eq!(call_error.to_string(), expected_error_message);

obj.free();
}

Expand Down
5 changes: 5 additions & 0 deletions itest/rust/src/object_tests/object_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,11 @@ impl ObjPayload {
fn do_panic(&self) {
panic!("do_panic exploded");
}

// Obtain the line number of the panic!() call above; keep equidistant to do_panic() method.
pub fn get_panic_line() -> u32 {
line!() - 5
}
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
Expand Down

0 comments on commit 3722014

Please sign in to comment.