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::mem;
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
|
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::future::Future;
|
|
||||||
|
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::task::{spawn_blocking, Context, JoinHandle, Poll};
|
use crate::task::{spawn_blocking, Context, JoinHandle, Poll};
|
||||||
|
use crate::utils::Context as ErrorContext;
|
||||||
|
|
||||||
cfg_not_docs! {
|
cfg_not_docs! {
|
||||||
macro_rules! ret {
|
macro_rules! ret {
|
||||||
|
@ -67,6 +68,18 @@ pub enum ToSocketAddrsFuture<I> {
|
||||||
Done,
|
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> {
|
impl<I: Iterator<Item = SocketAddr>> Future for ToSocketAddrsFuture<I> {
|
||||||
type Output = io::Result<I>;
|
type Output = io::Result<I>;
|
||||||
|
|
||||||
|
@ -110,7 +123,9 @@ impl ToSocketAddrs for SocketAddrV4 {
|
||||||
impl Future<Output = Self::Iter>,
|
impl Future<Output = Self::Iter>,
|
||||||
ToSocketAddrsFuture<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>,
|
impl Future<Output = Self::Iter>,
|
||||||
ToSocketAddrsFuture<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 host = host.to_string();
|
||||||
let task = spawn_blocking(move || {
|
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)
|
ToSocketAddrsFuture::Resolving(task)
|
||||||
}
|
}
|
||||||
|
@ -215,7 +234,10 @@ impl ToSocketAddrs for str {
|
||||||
}
|
}
|
||||||
|
|
||||||
let addr = self.to_string();
|
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)
|
ToSocketAddrsFuture::Resolving(task)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ use crate::net::driver::Watcher;
|
||||||
use crate::net::{TcpStream, ToSocketAddrs};
|
use crate::net::{TcpStream, ToSocketAddrs};
|
||||||
use crate::stream::Stream;
|
use crate::stream::Stream;
|
||||||
use crate::task::{Context, Poll};
|
use crate::task::{Context, Poll};
|
||||||
use crate::utils::Context as _;
|
|
||||||
|
|
||||||
/// A TCP socket server, listening for connections.
|
/// A TCP socket server, listening for connections.
|
||||||
///
|
///
|
||||||
|
@ -78,8 +77,7 @@ impl TcpListener {
|
||||||
let mut last_err = None;
|
let mut last_err = None;
|
||||||
let addrs = addrs
|
let addrs = addrs
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.await
|
.await?;
|
||||||
.context(|| String::from("could not resolve addresses"))?;
|
|
||||||
|
|
||||||
for addr in addrs {
|
for addr in addrs {
|
||||||
match mio::net::TcpListener::bind(&addr) {
|
match mio::net::TcpListener::bind(&addr) {
|
||||||
|
|
|
@ -74,8 +74,7 @@ impl TcpStream {
|
||||||
let mut last_err = None;
|
let mut last_err = None;
|
||||||
let addrs = addrs
|
let addrs = addrs
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.await
|
.await?;
|
||||||
.context(|| String::from("could not resolve addresses"))?;
|
|
||||||
|
|
||||||
for addr in addrs {
|
for addr in addrs {
|
||||||
let res = spawn_blocking(move || {
|
let res = spawn_blocking(move || {
|
||||||
|
|
|
@ -71,8 +71,7 @@ impl UdpSocket {
|
||||||
let mut last_err = None;
|
let mut last_err = None;
|
||||||
let addrs = addrs
|
let addrs = addrs
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.await
|
.await?;
|
||||||
.context(|| String::from("could not resolve addresses"))?;
|
|
||||||
|
|
||||||
for addr in addrs {
|
for addr in addrs {
|
||||||
match mio::net::UdpSocket::bind(&addr) {
|
match mio::net::UdpSocket::bind(&addr) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use async_std::{fs, task};
|
use async_std::{fs, io, net::ToSocketAddrs, task};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn open_file() {
|
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