Ответ 1
Отложив в сторону "вы должны использовать Result
, где это возможно", да, это в основном то, как вы попадаете в панику в Rust. Имейте в виду, что "восстановить", возможно, не самый лучший способ сформулировать это в Rust. Вы действительно не выздоравливаете от паники в Rust, вы их изолируете, а затем обнаруживаете. Нет On Error Resume Next
: P.
Тем не менее, к вашему примеру есть две вещи. Во-первых, как получить сообщение о панике. Главное наблюдение заключается в том, что Any
, чтобы быть использованным, должно быть явно опущено к конкретному конкретному типу, который он содержит. В этом случае, поскольку сообщение о панике представляет собой &'static str
, вам нужно сделать снимок.
Во-вторых, есть новый API в ночном названии catch_panic
, который позволяет изолировать панику без необходимости запуска потока. Тем не менее, он имеет те же ограничения, что и порождение нового потока: вы не можете передать ссылку 'static
через границу изоляции. Обратите внимание, что это нестабильное дополнение; пока нет гарантий относительно стабильности, и вам понадобится ночной компилятор для доступа к нему.
Вот пример, который показывает оба из них. Вы также можете запустить это в руке ржавчины.
#![feature(catch_panic)]
use std::thread;
fn main() {
println!("Hello, world!");
let h = thread::spawn(|| {
thread::sleep_ms(500);
panic!("boom");
});
let r = h.join();
handle(r);
let r = thread::catch_panic(|| {
thread::sleep_ms(500);
panic!(String::from("boom again!"));
});
handle(r);
println!("Exiting main!");
}
fn handle(r: thread::Result<()>) {
match r {
Ok(r) => println!("All is well! {:?}", r),
Err(e) => {
if let Some(e) = e.downcast_ref::<&'static str>() {
println!("Got an error: {}", e);
} else {
println!("Got an unknown error: {:?}", e);
}
}
}
}