Cannot use bail! with anyhow::Result

Hi folks,

I implementing trait for my servers and I have an error on compile:

error[E0308]: mismatched types
  --> src/primary/traits/server.rs:18:53
   |
18 |   ...                   tokio::spawn(async move {
   |  _______________________________________________^
19 | | ...                       if let Err(err) = self.handle_connection(socket).await {
20 | | ...                           bail!(
21 | | ...                               "[{}]: Error handling connection: {}",
...  |
27 | | ...                       drop(shutdown_tx);
28 | | ...                   });
   | |_______________________^ expected `Result<_, Error>`, found `()`
   |
   = note:   expected enum `Result<_, anyhow::Error>`
           found unit type `()`

this is my trait:

pub trait Server {
    async fn run(&mut self) -> AnyResult<()> {
        let (shutdown_tx, mut shutdown_rx) = mpsc::channel::<()>(1);

        let listener = TcpListener::bind(format!("{}:{}", Self::host(), Self::port())).await?;
        println!("[{}] is started on port {}", Self::server_name(), Self::port().to_string());

        loop {
            tokio::select! {
                stream = listener.accept() => {
                    match stream {
                        Ok((socket, _)) => {
                            let shutdown_tx = shutdown_tx.clone();
                            tokio::spawn(async move {
                                if let Err(err) = self.handle_connection(socket).await {
                                    bail!(
                                        "[{}]: Error handling connection: {}",
                                        Self::server_name(),
                                        err
                                    );
                                }

                                drop(shutdown_tx);
                            });
                        },
                        Err(err) => {
                            bail!("Error accepting connection: {}", err);
                        }
                    }
                },
                _ = shutdown_rx.recv() => {
                    break;
                }
            }
        }

        Ok(())
    }

    async fn handle_connection(&mut self, socket: TcpStream) -> AnyResult<()>;

    // ...
}

Could somebody explain what I did wrong ?

The bail! macro will attempt to return a Result, but the end of your tokio::spawn returns an (). These types must match.

Try adding Ok(()) to the end of your spawn.

Also, keep in mind that you are not using the JoinHandle returned by tokio::spawn, so any errors returned by the task will just be lost. It is probably better to handle the errors inside the task than to return them.

5 Likes

Thank you. Adding Ok(()) to the end of the spawn solved the issue. I will keep in mind your warning about errors handling, thanks !