Skip to content

Commit 3722014

Browse files
authored
Merge pull request #926 from 0x53A/dev
in debug, include location information in error message on panic
2 parents 387bd81 + 6eaae57 commit 3722014

File tree

3 files changed

+48
-14
lines changed

3 files changed

+48
-14
lines changed

godot-core/src/private.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -387,27 +387,39 @@ where
387387
// Handle panic info only in Debug mode.
388388
#[cfg(debug_assertions)]
389389
{
390-
let guard = info.lock().unwrap();
391-
let info = guard.as_ref().expect("no panic info available");
390+
let msg = extract_panic_message(err);
391+
let mut msg = format_panic_message(msg);
392+
393+
// Try to add location information.
394+
if let Ok(guard) = info.lock() {
395+
if let Some(info) = guard.as_ref() {
396+
msg = format!("{}\n at {}:{}", msg, info.file, info.line);
397+
}
398+
}
399+
392400
if print {
393401
godot_error!(
394-
"Rust function panicked at {}:{}.\n Context: {}",
395-
info.file,
396-
info.line,
402+
"Rust function panicked: {}\n Context: {}",
403+
msg,
397404
error_context()
398405
);
399406
//eprintln!("Backtrace:\n{}", info.backtrace);
400407
}
408+
409+
Err(msg)
401410
}
402411

403-
let msg = extract_panic_message(err);
404-
let msg = format_panic_message(msg);
412+
#[cfg(not(debug_assertions))]
413+
{
414+
let msg = extract_panic_message(err);
415+
let msg = format_panic_message(msg);
416+
417+
if print {
418+
godot_error!("{msg}");
419+
}
405420

406-
if print {
407-
godot_error!("{msg}");
421+
Err(msg)
408422
}
409-
410-
Err(msg)
411423
}
412424
}
413425
}

itest/rust/src/object_tests/dynamic_call_test.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,30 @@ fn dynamic_call_with_panic() {
148148

149149
assert_eq!(call_error.class_name(), Some("Object"));
150150
assert_eq!(call_error.method_name(), "call");
151-
assert_eq!(
152-
call_error.to_string(),
151+
152+
let appendix = if cfg!(debug_assertions) {
153+
let mut path = "itest/rust/src/object_tests/object_test.rs".to_string();
154+
155+
if cfg!(target_os = "windows") {
156+
path = path.replace('/', "\\")
157+
}
158+
159+
// Obtain line number dynamically, avoids tedious maintenance on code reorganization.
160+
let line = ObjPayload::get_panic_line();
161+
162+
format!("\n at {path}:{line}")
163+
} else {
164+
String::new()
165+
};
166+
167+
let expected_error_message = format!(
153168
"godot-rust function call failed: Object::call(&\"do_panic\")\
154169
\n Source: ObjPayload::do_panic()\
155-
\n Reason: [panic] do_panic exploded"
170+
\n Reason: [panic] do_panic exploded{appendix}"
156171
);
157172

173+
assert_eq!(call_error.to_string(), expected_error_message);
174+
158175
obj.free();
159176
}
160177

itest/rust/src/object_tests/object_test.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,11 @@ impl ObjPayload {
887887
fn do_panic(&self) {
888888
panic!("do_panic exploded");
889889
}
890+
891+
// Obtain the line number of the panic!() call above; keep equidistant to do_panic() method.
892+
pub fn get_panic_line() -> u32 {
893+
line!() - 5
894+
}
890895
}
891896

892897
// ----------------------------------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)