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.
pull/571/head
Pascal Hertleif 5 years ago
parent aa7d1c27a4
commit 56538ebd91

@ -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…
Cancel
Save