Maybe I'm not understanding the difference in syntax, but when I use async {} in my program, my attempts to use x.await.map_err(|e| CustomError(e))? complains that .map_err cannot be called on a unit type ().
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
--> src/main.rs:13:21
|
13 | let _conn = tokio::net::TcpListener::bind(&addr).await.map_err(|_err| "help")?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `std::ops::Try` is not implemented for `()`
= note: required by `std::ops::Try::from_error`
use std::error::Error;
#[tokio::main]
async fn main() {
fails().await.unwrap();
works().await.unwrap();
}
async fn fails() -> Result<(), Box<dyn Error>> {
let addr = "127.0.0.1:8888".parse::<std::net::SocketAddr>()?;
let server = async {
let _conn = tokio::net::TcpListener::bind(&addr).await.map_err(|_err| "help")?;
};
server.await;
Ok(())
}
async fn works() -> Result<(), Box<dyn Error>> {
let addr = "127.0.0.1:8888".parse::<std::net::SocketAddr>()?;
let _conn = tokio::net::TcpListener::bind(&addr).await.map_err(|_err| "help")?;
Ok(())
}
Thank you. I'm complete crap at reading rustc errors sometimes. I thought the message was complaining about .await returning (). Why? Because the project I was trying to build a simple, concise example for had more subsequent code in the async block and reported...
error[E0599]: no method named `map_err` found for type `()` in the current scope
--> src/bin/fuzzyd/main.rs:279:10
|
278 | let conn = tokio::net::TcpListener(&addr).await
279 | .map_err(|e| Error::from(ErrorKind::AppTask("server shutdown", e)))?;
| ^^^^^^^ method not found in `()`
|
= note: the method `map_err` exists but the following trait bounds were not satisfied:
`&() : futures_util::future::try_future::TryFutureExt`
`&() : futures_util::stream::try_stream::TryStreamExt`
`&mut () : futures_util::future::try_future::TryFutureExt`
`&mut () : futures_util::stream::try_stream::TryStreamExt`
`() : futures_util::future::try_future::TryFutureExt`
`() : futures_util::stream::try_stream::TryStreamExt`
I had to add Ok(()) as Result<(), &'static str> to satisfy a lack of type inference, but the fails() function compiles.
Then I added Ok(()) to the bottom of my project's async block, and this E0599 error is gone. Hopefully never to return!
I think the error message is just bad in this case, it doesn't say anything about the async block which is where the error lies. Could you file a bug for this?
Well, E0277 seems to be sorted in rustc-1.41.0-nightly, and clearly mentions the async block as the source of the (). No bug report needed there.
error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
--> src/lib.rs:13:21
|
12 | let server = async {
| ________________________-
13 | | let _conn = tokio::net::TcpListener::bind(&addr).await.map_err(|_err| "help")?;
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in an async block that returns `()`
14 | | };
| |_____- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `std::ops::Try` is not implemented for `()`
= note: required by `std::ops::Try::from_error`
I couldn't reproduce the error E0599 I initially got. Without a reproducible example, I'll skip the bug report on this for now. If I stumble upon it again, I'll pursue a bug report at that time.
Indeed, that is the basis for both errors I saw. Though in my case, I failed to recognize that an async block is effectively a closure as KrishnaSannasi pointed out.