How to handle panics in async tasks

Handle panics in async tasks by isolating them in separate OS threads using std::thread::spawn and panic::catch_unwind to prevent process-wide crashes.

You cannot directly catch panics inside an async task because the async runtime will abort the entire process if a panic occurs. To handle panics safely, you must spawn the async task on a separate OS thread using std::thread::spawn and wrap the panic-prone logic in a catch_unwind block, or use a runtime that supports panic recovery like tokio::task::spawn_blocking combined with manual thread management. Here is a minimal example using std::thread::spawn to isolate the panic:

use std::thread;
use std::panic::{self, AssertUnwindSafe};
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();

    let handle = thread::spawn(move || {
        let result = panic::catch_unwind(AssertUnwindSafe(|| {
            // Simulate async work that might panic
            panic!("Oops!");
        }));

        tx.send(result).unwrap();
    });

    handle.join().unwrap();

    match rx.recv().unwrap() {
        Ok(_) => println!("Task completed successfully"),
        Err(_) => println!("Task panicked"),
    }
}

Note: This example uses synchronous threads. For true async work, you would typically run the async runtime inside the spawned thread or use a library like tokio with spawn_blocking for CPU-bound tasks, but panic recovery still requires thread-level isolation.