MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / install_enhanced_handler

Function install_enhanced_handler

src/ore/src/panic.rs:134–280  ·  view source on GitHub ↗

Overwrites the default panic handler with an enhanced panic handler. The enhanced panic handler: Always emits a backtrace, regardless of how `RUST_BACKTRACE` was configured. Writes to stderr as atomically as possible, to minimize interleaving with concurrent log messages. Reports panics to Sentry. Sentry installs its own panic hook by default that reports the panic and then forwards it to the

()

Source from the content-addressed store, hash-verified

132/// recover. Note that the `catch_unwind` function in the standard library is
133/// **not** compatible with this improved panic handler.
134pub fn install_enhanced_handler() {
135 panic::set_hook(Box::new(move |panic_info| {
136 // If we're catching an unwind, do nothing to let the unwind handler
137 // run.
138 let catching_unwind = CATCHING_UNWIND.with(|v| *v.borrow());
139 #[cfg(feature = "async")]
140 let catching_unwind_async = CATCHING_UNWIND_ASYNC.try_with(|v| *v).unwrap_or(false);
141 #[cfg(not(feature = "async"))]
142 let catching_unwind_async = false;
143 if catching_unwind != 0 || catching_unwind_async {
144 // We're letting the unwind proceed without printing or reporting the
145 // panic. The location and backtrace would normally be lost here,
146 // because `catch_unwind` only recovers the panic payload (the
147 // message). If a caller has opted in via `catch_unwind_with_details`,
148 // stash those details now so they can be attached to the resulting
149 // error. We only pay the cost of capturing a backtrace when a panic
150 // actually occurs, which is the exceptional case.
151 let capture_details = CAPTURE_PANIC_DETAILS.with(|v| *v.borrow()) != 0;
152 if capture_details {
153 let location = panic_info.location().map(|loc| loc.to_string());
154 let backtrace = Backtrace::force_capture().to_string();
155 CAUGHT_PANIC_DETAILS.with(|details| {
156 *details.borrow_mut() = Some(PanicDetails {
157 location,
158 backtrace,
159 });
160 });
161 }
162 return;
163 }
164
165 // Report the panic to Sentry.
166 // Note that we can't use `sentry_panic::panic_handler` because that requires the panic
167 // integration to be enabled.
168 sentry::Hub::with_active(|hub| {
169 let event = sentry_panic::PanicIntegration::new().event_from_panic_info(panic_info);
170 hub.capture_event(event);
171 if let Some(client) = hub.client() {
172 client.flush(None);
173 }
174 });
175
176 // can't use if cfg!() here because that will require chrono::Utc import
177 #[cfg(feature = "chrono")]
178 let timestamp = Utc::now().format("%Y-%m-%dT%H:%M:%S%.6fZ ").to_string();
179 #[cfg(not(feature = "chrono"))]
180 let timestamp = String::new();
181
182 let thread = thread::current();
183 let thread_name = thread.name().unwrap_or("<unnamed>");
184
185 let msg = match panic_info.payload().downcast_ref::<&'static str>() {
186 Some(s) => *s,
187 None => match panic_info.payload().downcast_ref::<String>() {
188 Some(s) => &s[..],
189 None => "Box<Any>",
190 },
191 };

Callers 7

mainFunction · 0.85
catch_panic_asyncFunction · 0.85
catch_panicFunction · 0.85
mainFunction · 0.85
runFunction · 0.85
mainFunction · 0.85
runFunction · 0.85

Calls 15

nowFunction · 0.85
currentFunction · 0.85
spawnFunction · 0.85
cloneFunction · 0.85
sleepFunction · 0.85
is_someMethod · 0.80
chain_oneMethod · 0.80
take_whileMethod · 0.80
lockMethod · 0.80
unwrapMethod · 0.80
borrowMethod · 0.45
mapMethod · 0.45

Tested by 3

catch_panic_asyncFunction · 0.68
catch_panicFunction · 0.68
mainFunction · 0.68