How can I check if the error from try_bind_with_graceful_shutdown
is std::io::ErrorKind::AddrInUse
?
Asked
Active
Viewed 416 times
0

Shepmaster
- 388,571
- 95
- 1,107
- 1,366

Lightstorm
- 379
- 4
- 5
-
1It is a warp::Error not an `std::io::Error`, I dont think you can do it straight away. – Netwave Aug 31 '21 at 16:10
-
1With the way it's currently implemented (https://docs.rs/warp/0.3.1/src/warp/error.rs.html), it doesn't look like there are any great options, the options I can come up with are the compare the `Debug` and/or `Display` output strings, or to use `unsafe` code to get `inner` and *hope* it works (since there's no `#[repr(transparent)]` or `#[repr(C)]`) to extract the inner value, then use `downcast_ref` (https://doc.rust-lang.org/std/any/trait.Any.html#method.downcast_ref-2). I'd recommend finding a different way of solving this or filing an issue at https://github.com/seanmonstar/warp/issues. – Solomon Ucko Aug 31 '21 at 17:01
-
Resists the temptation and the comments suggesting to parse the output of `Display` or `Debug`, and instead re-implement [what `warp` does itself](https://docs.rs/warp/0.3.1/src/warp/server.rs.html#296-310) in `try_bind...` – user2722968 Aug 31 '21 at 17:42
1 Answers
1
If you are using warp
from the repository (instead of from crates.io), you can combine Error::source()
with Error::downcast_ref()
to do what you want:
let hello = warp::path!("hello" / String)
.map(|name| format!("Hello, {}!", name));
match warp::serve(hello).try_bind_with_graceful_shutdown(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 8081), std::future::pending()) {
Ok((_, future)) => future.await,
Err(error) => {
use std::error::Error;
let mut current_error: &dyn Error = &error;
let is_because_of_addr_in_use = loop {
// get source of the error...
current_error = match current_error.source() {
// if there is one, continue
Some(source) => source,
// else, this error is not because of AddrInUse
None => break false
};
//if the source is of type `std::io::Error`
if let Some(io_error) = current_error.downcast_ref::<std::io::Error>() {
break io_error.kind() == std::io::ErrorKind::AddrInUse;
}
};
println!("Failed. is_because_of_addr_in_use == {}", is_because_of_addr_in_use);
}
};
This prints Failed. is_because_of_addr_in_use == true
if and only if warp
failed to bind to the SocketAddr
because it is already in use.
Note that this does not work for released versions of warp
because the pull request implementing Error::source
for warp::Error
is not yet released. If you are using a released version of warp
, your best bet for now is probably to parse the output generated by the Debug
or the Display
implementation of warp::Error
.

Elias Holzmann
- 3,216
- 2
- 17
- 33