@qid00000000
Мало что знаю, но информацию найду в гугле

Как преобразовать ошибку потока Rust в строку?

Всем привет, немного изучаю concurency и столкнулся с тем, что не могу вывести сообщение паники из потока:
Исходный код:
use std::thread;
use std::time::Duration;

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {} from the spawned thread!", i);
            thread::sleep(Duration::from_millis(1));
        }

        panic!("failed to spawn");
    });

    for i in 1..5 {
        println!("hi number {} from the main thread!", i);
        thread::sleep(Duration::from_millis(1));
    }

    println!("Wait");
    while !handle.is_finished() {
        thread::sleep(Duration::from_secs(1));
    }
    println!("Finish");

    match handle.join() {
        Ok(res) => println!("{:?}", res),
        Err(err) => {
            println!("{:?}", err);
        }
    }
}


Вывод
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the main thread!
hi number 2 from the spawned thread!
hi number 3 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the main thread!
hi number 4 from the spawned thread!
Wait
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!
thread '<unnamed>' panicked at 'failed to spawn', src/main.rs:71:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Finish
Any { .. }


71:9 - соответствует окончанию вызова thread::spawn.

match handle.join вернет Err(err: Box)

Попробовал преобразовать Box в строку как в примере: https://doc.rust-lang.org/std/any/trait.Any.html
fn print_if_string(value: Box<dyn Any>) {
    if let Ok(string) = value.downcast::<String>() {
        println!("String ({}): {}", string.len(), string);
    }
}


Но это не строка.

Есть у кого идеи - как можно определить тип чтобы преобразовать к строке и вывести причину ошибки?
  • Вопрос задан
  • 83 просмотра
Решения вопроса 2
vabka
@vabka
Токсичный шарпист
1. У Any есть метод is, с помощью которого можно проверить тип. В твоём случае это &'static str (собственно то, что ты в panic и засунул)
2. =>
Err(err) => {
            println!("{}", err.is::<&'static str>());
            let value = err.downcast::<&'static str>().unwrap();
            println!("{}", value); // Выводит строку failed to spawn
        }
Ответ написан
Комментировать
@qid00000000 Автор вопроса
Мало что знаю, но информацию найду в гугле
В одном из чатов подсказали &str в качестве типа downcast использовать. Что как оказалось логично, тк ловушка для panic содержит &str либо String: https://doc.rust-lang.org/std/macro.panic.html :

The behavior of the default std hook, i.e. the code that runs directly after the panic is invoked, is to print the message payload to stderr along with the file/line/column information of the panic!() call. You can override the panic hook using std::panic::set_hook(). Inside the hook a panic can be accessed as a &dyn Any + Send, which contains either a &str or String for regular panic!() invocations. To panic with a value of another other type, panic_any can be used.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы