WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Rust · Intermediate · question 30 of 100

How do you perform error handling across threads in Rust?

📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

In Rust, error handling across threads can be achieved using the ‘Result‘ type and the ‘panic!‘ macro. There are three common ways to handle errors across threads in Rust:

1. Propagating errors using ‘Result‘: When a thread encounters an error, it can propagate the error to the parent thread using the ‘Result‘ type. The parent thread can handle the error or propagate it further up the call stack. Here’s an example:

    use std::thread;
    
    fn main() -> Result<(), String> {
        let child = thread::spawn(|| {
            // Some error occurred
            Err("Something went wrong".to_string())
        });
        
        // Wait for the child thread to complete and propagate errors
        child.join().unwrap_or(Err("Child thread panicked".to_string()))?;
        
        // Do some other operations
        Ok(())
    }

In this example, the child thread returns an error using ‘Err‘ and the parent thread uses ‘unwrap_or‘ to handle the error if it’s present. If the child thread panics, the error message "Child thread panicked" is returned. Finally, the parent thread performs some other operations and returns ‘Ok(())‘.

2. Using message passing with channels: Another way to handle errors across threads is to use channels to pass error messages from child threads to parent threads. Here’s an example:

    use std::thread;
    use std::sync::mpsc;
    
    fn main() -> Result<(), String> {
        // Create a channel for sending and receiving error messages
        let (tx, rx) = mpsc::channel();
        
        // Create the child thread and pass the sender to it
        let child = thread::spawn(move || {
            // Some error occurred
            tx.send("Something went wrong".to_string()).unwrap();
        });
        
        // Wait for the child thread to complete
        child.join().unwrap_or_else(|_| {
            tx.send("Child thread panicked".to_string()).unwrap();
        });
        
        // Check for any error messages
        if let Ok(error_msg) = rx.try_recv() {
            return Err(error_msg);
        }
        
        // Do some other operations
        Ok(())
    }

In this example, the parent thread creates a channel and passes the sender to the child thread. The child thread sends an error message using ‘send()‘ method. If the child thread panics, the parent thread sends an error message. The parent thread checks for any error messages using the ‘try_recv()‘ method and returns an error if there’s a message. Finally, the parent thread performs some other operations and returns ‘Ok(())‘.

3. Using the ‘panic!‘ macro: The ‘panic!‘ macro can also be used to handle errors across threads. If a thread panics, the panic message can be caught by the parent thread using the ‘catch_unwind()‘ function. Here’s an example:

    use std::thread;
    
    fn main() -> Result<(), String> {
        let child = thread::spawn(|| {
            // Some error occurred
            panic!("Something went wrong");
        });
        
        if let Err(panic_obj) = child.join() {
            if let Some(error_msg) = panic_obj.downcast_ref::<&'static str>() {
                return Err(error_msg.to_string());
            }
            
            if let Some(error_msg) = panic_obj.downcast_ref::<String>() {
                return Err(error_msg.clone());
            }
            
            return Err("Child thread panicked with unknown error type".to_string());
        }
        
        // Do some other operations
        Ok(())
    }

In this example, the child thread panics using the ‘panic!‘ macro. The parent thread joins the child thread and catches the panic using ‘catch_unwind()‘. The panic object is downcasted to determine the error message type, and an error message is returned if the child thread panicked. If the child thread completed successfully, the parent thread performs some other operations and returns ‘Ok(())‘.

To summarize, error handling across threads in Rust can be achieved using the ‘Result‘ type, channels, or the ‘panic!‘ macro. Each method has its advantages and disadvantages, and the choice of method depends on the specific use case.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Rust interview — then scores it.
📞 Practice Rust — free 15 min
📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

All 100 Rust questions · All topics