headless_lms_utils/error/
backtrace_formatter.rs1use core::fmt;
6
7use backtrace::{Backtrace, BacktraceFmt, BacktraceFrame, PrintFmt, SymbolName};
8
9pub fn format_backtrace(backtrace: &Backtrace, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
15 let cwd = std::env::current_dir().ok();
16 let cwd_copy = cwd.clone();
17 let mut print_path = move |fmt: &mut fmt::Formatter<'_>,
18 path: backtrace::BytesOrWideString<'_>| {
19 let cwd_path_buf = path.into_path_buf();
20
21 if let Some(cwd) = &cwd_copy {
22 if let Ok(suffix) = cwd_path_buf.strip_prefix(cwd) {
23 return fmt::Display::fmt(&suffix.display(), fmt);
24 }
25 }
26
27 fmt::Display::fmt(&cwd_path_buf.display(), fmt)
28 };
29
30 let mut f = BacktraceFmt::new(fmt, PrintFmt::Short, &mut print_path);
31 f.add_context()?;
32
33 let mut skipped_n_frames = 0;
34 let frames = backtrace.frames();
35 for frame in frames.iter().skip(1) {
37 let frame_from_this_project = frame.symbols().iter().any(|symbol| {
38 symbol
39 .filename()
40 .map(|path| {
41 if let Some(cwd) = cwd.clone() {
42 path.starts_with(cwd)
44 } else {
45 false
46 }
47 })
48 .unwrap_or(false)
49 });
50 if !frame_from_this_project {
51 skipped_n_frames += 1;
52 continue;
53 } else {
54 if skipped_n_frames > 0 {
55 print_filtered_frame_placeholder(skipped_n_frames, &mut f, frame)?;
56 }
57 skipped_n_frames = 0;
58 }
59
60 f.frame().backtrace_frame(frame)?;
61 }
62 if skipped_n_frames > 0 {
63 if let Some(some_frame) = frames.first() {
65 print_filtered_frame_placeholder(skipped_n_frames, &mut f, some_frame)?;
66 }
67 }
68
69 f.finish()?;
70 Ok(())
71}
72
73fn print_filtered_frame_placeholder(
74 skipped_n_frames: i32,
75 f: &mut BacktraceFmt,
76 reference_frame: &BacktraceFrame,
77) -> fmt::Result {
78 let mut backtrace_frame_fmt = f.frame();
79 let word = if skipped_n_frames == 1 {
80 "frame"
81 } else {
82 "frames"
83 };
84 backtrace_frame_fmt.print_raw(
85 reference_frame.ip(),
87 Some(SymbolName::new(
88 format!("<----- {} filtered {} ----->", skipped_n_frames, word).as_bytes(),
89 )),
90 None,
91 None,
92 )?;
93 Ok(())
94}