forked from mirror/async-std
Improve verbose errors for socket addresses
Moves the point of adding error context to the net::addr module so that we have access to the raw address input and can include it in the error message.
This commit is contained in:
parent
aa7d1c27a4
commit
56538ebd91
5 changed files with 46 additions and 13 deletions
|
@ -1,11 +1,12 @@
|
|||
use std::future::Future;
|
||||
use std::mem;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
use std::pin::Pin;
|
||||
use std::future::Future;
|
||||
|
||||
use crate::io;
|
||||
use crate::task::{spawn_blocking, Context, JoinHandle, Poll};
|
||||
use crate::utils::Context as ErrorContext;
|
||||
|
||||
cfg_not_docs! {
|
||||
macro_rules! ret {
|
||||
|
@ -67,6 +68,18 @@ pub enum ToSocketAddrsFuture<I> {
|
|||
Done,
|
||||
}
|
||||
|
||||
/// Wrap `std::io::Error` with additional message
|
||||
///
|
||||
/// Keeps the original error kind and stores the original I/O error as `source`.
|
||||
impl<T> ErrorContext for ToSocketAddrsFuture<T> {
|
||||
fn context(self, message: impl Fn() -> String) -> Self {
|
||||
match self {
|
||||
ToSocketAddrsFuture::Ready(res) => ToSocketAddrsFuture::Ready(res.context(message)),
|
||||
x => x,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Iterator<Item = SocketAddr>> Future for ToSocketAddrsFuture<I> {
|
||||
type Output = io::Result<I>;
|
||||
|
||||
|
@ -110,7 +123,9 @@ impl ToSocketAddrs for SocketAddrV4 {
|
|||
impl Future<Output = Self::Iter>,
|
||||
ToSocketAddrsFuture<Self::Iter>
|
||||
) {
|
||||
SocketAddr::V4(*self).to_socket_addrs()
|
||||
SocketAddr::V4(*self)
|
||||
.to_socket_addrs()
|
||||
.context(|| format!("could not resolve address `{}`", self))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +138,9 @@ impl ToSocketAddrs for SocketAddrV6 {
|
|||
impl Future<Output = Self::Iter>,
|
||||
ToSocketAddrsFuture<Self::Iter>
|
||||
) {
|
||||
SocketAddr::V6(*self).to_socket_addrs()
|
||||
SocketAddr::V6(*self)
|
||||
.to_socket_addrs()
|
||||
.context(|| format!("could not resolve address `{}`", self))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +212,9 @@ impl ToSocketAddrs for (&str, u16) {
|
|||
|
||||
let host = host.to_string();
|
||||
let task = spawn_blocking(move || {
|
||||
std::net::ToSocketAddrs::to_socket_addrs(&(host.as_str(), port))
|
||||
let addr = (host.as_str(), port);
|
||||
std::net::ToSocketAddrs::to_socket_addrs(&addr)
|
||||
.context(|| format!("could not resolve address `{:?}`", addr))
|
||||
});
|
||||
ToSocketAddrsFuture::Resolving(task)
|
||||
}
|
||||
|
@ -215,7 +234,10 @@ impl ToSocketAddrs for str {
|
|||
}
|
||||
|
||||
let addr = self.to_string();
|
||||
let task = spawn_blocking(move || std::net::ToSocketAddrs::to_socket_addrs(addr.as_str()));
|
||||
let task = spawn_blocking(move || {
|
||||
std::net::ToSocketAddrs::to_socket_addrs(addr.as_str())
|
||||
.context(|| format!("could not resolve address `{:?}`", addr))
|
||||
});
|
||||
ToSocketAddrsFuture::Resolving(task)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use crate::net::driver::Watcher;
|
|||
use crate::net::{TcpStream, ToSocketAddrs};
|
||||
use crate::stream::Stream;
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::utils::Context as _;
|
||||
|
||||
/// A TCP socket server, listening for connections.
|
||||
///
|
||||
|
@ -78,8 +77,7 @@ impl TcpListener {
|
|||
let mut last_err = None;
|
||||
let addrs = addrs
|
||||
.to_socket_addrs()
|
||||
.await
|
||||
.context(|| String::from("could not resolve addresses"))?;
|
||||
.await?;
|
||||
|
||||
for addr in addrs {
|
||||
match mio::net::TcpListener::bind(&addr) {
|
||||
|
|
|
@ -74,8 +74,7 @@ impl TcpStream {
|
|||
let mut last_err = None;
|
||||
let addrs = addrs
|
||||
.to_socket_addrs()
|
||||
.await
|
||||
.context(|| String::from("could not resolve addresses"))?;
|
||||
.await?;
|
||||
|
||||
for addr in addrs {
|
||||
let res = spawn_blocking(move || {
|
||||
|
|
|
@ -71,8 +71,7 @@ impl UdpSocket {
|
|||
let mut last_err = None;
|
||||
let addrs = addrs
|
||||
.to_socket_addrs()
|
||||
.await
|
||||
.context(|| String::from("could not resolve addresses"))?;
|
||||
.await?;
|
||||
|
||||
for addr in addrs {
|
||||
match mio::net::UdpSocket::bind(&addr) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use async_std::{fs, task};
|
||||
use async_std::{fs, io, net::ToSocketAddrs, task};
|
||||
|
||||
#[test]
|
||||
fn open_file() {
|
||||
|
@ -14,3 +14,18 @@ fn open_file() {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_address() {
|
||||
task::block_on(async {
|
||||
let non_existing_addr = "ashjudlkahasdasdsikdhajik.asdasdasdasdasdasd.fjuiklashdbflasas:80";
|
||||
let res: Result<_, io::Error> = non_existing_addr.to_socket_addrs().await;
|
||||
match res {
|
||||
Ok(_) => panic!("Found address with random name: We live in a simulation"),
|
||||
Err(e) => assert_eq!(
|
||||
"could not resolve address `\"ashjudlkahasdasdsikdhajik.asdasdasdasdasdasd.fjuiklashdbflasas:80\"`",
|
||||
&format!("{}", e)
|
||||
),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue