azure_functions/
backtrace.rs1use backtrace::BacktraceFrame;
2use std::env;
3use std::fmt;
4
5pub struct Backtrace {
6 inner: backtrace::Backtrace,
7}
8
9impl Backtrace {
10 pub fn new() -> Backtrace {
11 if !Backtrace::is_enabled() {
12 return Backtrace {
13 inner: Vec::<BacktraceFrame>::new().into(),
14 };
15 }
16
17 let mut found_start = false;
18 let mut found_end = false;
19
20 let frames: Vec<BacktraceFrame> = backtrace::Backtrace::new()
22 .frames()
23 .iter()
24 .filter_map(|frame| {
25 if found_end {
26 return None;
27 }
28
29 for symbol in frame.symbols() {
30 if let Some(name) = symbol.name() {
31 let name = format!("{}", name);
32
33 if !found_start {
35 if name.starts_with("std::panicking::begin_panic::")
36 || name.starts_with("core::panicking::panic::")
37 {
38 found_start = true;
39 }
40 return None;
41 }
42
43 if !found_end && name.contains("::__invoke_") {
45 found_end = true;
46 return None;
47 }
48 }
49 }
50
51 Some(frame.clone())
52 })
53 .collect();
54
55 Backtrace {
56 inner: frames.into(),
57 }
58 }
59
60 pub fn is_enabled() -> bool {
61 env::var("RUST_BACKTRACE").unwrap_or_else(|_| "0".to_owned()) == "1"
62 }
63}
64
65impl fmt::Display for Backtrace {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 use std::fmt::Debug;
68
69 if !Backtrace::is_enabled() {
70 return write!(
71 f,
72 "\nNote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace."
73 );
74 }
75
76 if self.inner.frames().is_empty() {
77 return Ok(());
78 }
79
80 writeln!(f)?;
81 self.inner.fmt(f)
82 }
83}