3

as a JS dev i'm having a real hard time understanding error handling in rust. especially with asyncronisity. heres some code from another stackoverflow question using async-std to call an async scraper function:

use std::fs::File;
use std::io::{self, BufReader};
use std::io::BufRead;
//use async_std::task;

async fn scrape<R: BufRead>(reader: &mut R) -> io::Result<()> {
    reader.lines()
        .try_for_each(|line_result| line_result.and_then(|line| Ok(println!("{}", line))))?;
    Ok(())
}

fn main() {
    let file_result = File::open("wlist.txt");
    let file;
    match file_result {
       Ok(f) => file = f,
       Err(e) => { println!("File open error! {}", e); return; },
    }
    let mut reader = BufReader::new(file);

    match scrape(&mut reader) {
        Ok(_) => println!("done!"),
        Err(e) => println!("File read error! {}", e),
    }
}

I'm trying to call scrape in an asyncronous way like:

    task::block_on(match scrape(&mut reader) {
        Ok(_) => println!("done!"),
        Err(e) => println!("File read error! {}", e),
    })

but it errors with the trait std::future::Future is not implemented for ()

What's wrong with the code snippet? how can I run scraper as async with as less modification to the rest of the code as possible?

1 Answer 1

2

Usually you can only call async functions from async context, except when you use the block_on or spawn functions or similar from your executor.

The easiest way to create an async context is an async block. Then you need to use the .await operator to properly chain asyncs:

    task::block_on(async {
        match scrape(&mut reader).await {
            Ok(_) => println!("done!"),
            Err(e) => println!("File read error! {}", e),
        }
    })

For more complex code you will have an async function that may fail that calls another async function that also may fail. In those cases it is idiomatic to write other_async_func().await? to await and forward the error at the same time.

Sign up to request clarification or add additional context in comments.

2 Comments

this returns ``` error[E0277]: the trait bound std::result::Result<(), std::io::Error>: std::future::Future is not satisfied --> src\main.rs:22:15 | 22 | match scrape(&mut reader).await { | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait std::future::Future is not implemented for `std::result::Result<(), std::io::Error ```
This means that you are using .await is something that is not a Future, probably because you removed the async from async fn scrape(...). Either add async to the function or remove the .await from the call. Naturally, your code does not have any async I/O so it will make no difference in practice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.