Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I solve the error "thread 'main' panicked at 'no current reactor'"?

I am trying to connect to a database:

extern crate tokio; // 0.2.6, features = ["full"]
extern crate tokio_postgres; // 0.5.1

use futures::executor;
use tokio_postgres::NoTls;

fn main() {
    let fut = async {
        let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
            Ok((client, connection)) => (client, connection),
            Err(e) => panic!(e),
        };
        tokio::spawn(async move {
            if let Err(e) = connection.await {
                eprintln!("connection error: {}", e);
            }
        });

        let rows = match client
            .query(
                "SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
                &[&"name"],
            )
            .await
        {
            Ok(rows) => rows,
            Err(e) => panic!(e),
        };
        let names: &str = rows[0].get("name");
        println!("{:?}", names);
    };
    executor::block_on(fut);
    println!("Hello, world!");
}

It compiled, but when I ran it, I received the error message

thread 'main' panicked at 'no current reactor'
like image 572
julia Avatar asked Nov 07 '22 10:11

julia


1 Answers

When using many (but not all) Tokio features, you must use the Tokio reactor. In your code, you are trying to use the general executor provided by the futures crate (executor::block_on). Using the Tokio executor and reactor is normally done via use of the #[tokio::main] macro:

#[tokio::main]
async fn main() {
    let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
        Ok((client, connection)) => (client, connection),
        Err(e) => panic!(e),
    };
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("connection error: {}", e);
        }
    });

    let rows = match client
        .query(
            "SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
            &[&"name"],
        )
        .await
    {
        Ok(rows) => rows,
        Err(e) => panic!(e),
    };
    let names: &str = rows[0].get("name");
    println!("{:?}", names);
}

The very first example in the tokio_postgres docs even shows you how to do this:

#[tokio::main] // By default, tokio_postgres uses the tokio crate as its runtime.
async fn main() -> Result<(), Error> {

One reason this happens is because you are using tokio::spawn which has this documented:

Panics if called from outside of the Tokio runtime.

See also:

  • How do I synchronously return a value calculated in an asynchronous Future in stable Rust?

This doesn't print what you want:

Err(e) => panic!(e),

You want

Err(e) => panic!("{}", e),
like image 165
Shepmaster Avatar answered Nov 16 '22 16:11

Shepmaster