# Objective
Make `bevy_error_panic_hook` threadsafe. As it relies on a global
variable, it fails when multiple threads panic.
## Solution
Switch from a global variable for storing whether an error message was
printed to a thread-local one.
`thread_local` is in `std`; the `backtrace` already relies on `std`
APIs. It didn't depend on the `std` feature though, so I've added that.
I've also put `bevy_error_panic_hook` behind the `backtrace` feature,
since it relies on the thread local variable, which fixes#18231.
## Testing
The following now loops instead of crashing:
```rust
std:🧵:scope(|s| {
use bevy_ecs::error::*;
#[derive(Debug)]
struct E;
impl std::fmt::Display for E {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
todo!()
}
}
impl std::error::Error for E {}
std::panic::set_hook(Box::new(bevy_error_panic_hook(|_| {
unreachable!();
})));
for _ in 0..2 {
s.spawn(|| {
loop {
let _ = std::panic::catch_unwind(|| {
panic!("{:?}", BevyError::from(E));
});
}
});
}
});
```