summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorLiran Ringel <5730310+liranringel@users.noreply.github.com>2018-11-20 18:10:36 +0200
committerToby Lawrence <tobz@users.noreply.github.com>2018-11-20 11:10:36 -0500
commit9b1a45cc6a15f5d2be17531dffc2f50d2b019646 (patch)
treeda66c5c9574f2cd7ad11745e414fc34da2e35c6f /examples
parent477fa5580aa3796f97e3e0eb1325d4690b3b4e96 (diff)
tests: handle errors properly in examples (#748)
Diffstat (limited to 'examples')
-rw-r--r--examples/chat-combinator.rs14
-rw-r--r--examples/chat.rs7
-rw-r--r--examples/connect.rs48
-rw-r--r--examples/echo-udp.rs9
-rw-r--r--examples/echo.rs7
-rw-r--r--examples/hello_world.rs6
-rw-r--r--examples/manual-runtime.rs5
-rw-r--r--examples/print_each_packet.rs7
-rw-r--r--examples/proxy.rs9
-rw-r--r--examples/tinydb.rs7
-rw-r--r--examples/tinyhttp.rs51
-rw-r--r--examples/udp-client.rs27
-rw-r--r--examples/udp-codec.rs11
13 files changed, 114 insertions, 94 deletions
diff --git a/examples/chat-combinator.rs b/examples/chat-combinator.rs
index 11754183..0572afbd 100644
--- a/examples/chat-combinator.rs
+++ b/examples/chat-combinator.rs
@@ -34,12 +34,12 @@ use std::env;
use std::io::{BufReader};
use std::sync::{Arc, Mutex};
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
// Create the TCP listener we'll accept connections on.
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
- let addr = addr.parse().unwrap();
+ let addr = addr.parse()?;
- let socket = TcpListener::bind(&addr).unwrap();
+ let socket = TcpListener::bind(&addr)?;
println!("Listening on: {}", addr);
// This is running on the Tokio runtime, so it will be multi-threaded. The
@@ -49,10 +49,10 @@ fn main() {
// The server task asynchronously iterates over and processes each incoming
// connection.
let srv = socket.incoming()
- .map_err(|e| println!("failed to accept socket; error = {:?}", e))
+ .map_err(|e| {println!("failed to accept socket; error = {:?}", e); e})
.for_each(move |stream| {
// The client's socket address
- let addr = stream.peer_addr().unwrap();
+ let addr = stream.peer_addr()?;
println!("New Connection: {}", addr);
@@ -143,8 +143,10 @@ fn main() {
}));
Ok(())
- });
+ })
+ .map_err(|err| println!("error occurred: {:?}", err));
// execute server
tokio::run(srv);
+ Ok(())
}
diff --git a/examples/chat.rs b/examples/chat.rs
index bdc742c9..182af7c8 100644
--- a/examples/chat.rs
+++ b/examples/chat.rs
@@ -426,7 +426,7 @@ fn process(socket: TcpStream, state: Arc<Mutex<Shared>>) {
tokio::spawn(connection);
}
-pub fn main() {
+pub fn main() -> Result<(), Box<std::error::Error>> {
// Create the shared state. This is how all the peers communicate.
//
// The server task will hold a handle to this. For every new client, the
@@ -434,12 +434,12 @@ pub fn main() {
// client connection.
let state = Arc::new(Mutex::new(Shared::new()));
- let addr = "127.0.0.1:6142".parse().unwrap();
+ let addr = "127.0.0.1:6142".parse()?;
// Bind a TCP listener to the socket address.
//
// Note that this is the Tokio TcpListener, which is fully async.
- let listener = TcpListener::bind(&addr).unwrap();
+ let listener = TcpListener::bind(&addr)?;
// The server task asynchronously iterates over and processes each
// incoming connection.
@@ -471,4 +471,5 @@ pub fn main() {
// In our example, we have not defined a shutdown strategy, so this will
// block until `ctrl-c` is pressed at the terminal.
tokio::run(server);
+ Ok(())
}
diff --git a/examples/connect.rs b/examples/connect.rs
index fa3824c4..93f55533 100644
--- a/examples/connect.rs
+++ b/examples/connect.rs
@@ -29,7 +29,7 @@ use std::thread;
use tokio::prelude::*;
use futures::sync::mpsc;
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
// Determine if we're going to run in TCP or UDP mode
let mut args = env::args().skip(1).collect::<Vec<_>>();
let tcp = match args.iter().position(|a| a == "--udp") {
@@ -41,10 +41,11 @@ fn main() {
};
// Parse what address we're going to connect to
- let addr = args.first().unwrap_or_else(|| {
- panic!("this program requires at least one argument")
- });
- let addr = addr.parse::<SocketAddr>().unwrap();
+ let addr = match args.first() {
+ Some(addr) => addr,
+ None => Err("this program requires at least one argument")?,
+ };
+ let addr = addr.parse::<SocketAddr>()?;
// Right now Tokio doesn't support a handle to stdin running on the event
// loop, so we farm out that work to a separate thread. This thread will
@@ -52,15 +53,15 @@ fn main() {
// loop over a standard futures channel.
let (stdin_tx, stdin_rx) = mpsc::channel(0);
thread::spawn(|| read_stdin(stdin_tx));
- let stdin_rx = stdin_rx.map_err(|_| panic!()); // errors not possible on rx
+ let stdin_rx = stdin_rx.map_err(|_| panic!("errors not possible on rx"));
// Now that we've got our stdin read we either set up our TCP connection or
// our UDP connection to get a stream of bytes we're going to emit to
// stdout.
let stdout = if tcp {
- tcp::connect(&addr, Box::new(stdin_rx))
+ tcp::connect(&addr, Box::new(stdin_rx))?
} else {
- udp::connect(&addr, Box::new(stdin_rx))
+ udp::connect(&addr, Box::new(stdin_rx))?
};
// And now with our stream of bytes to write to stdout, we execute that in
@@ -77,6 +78,7 @@ fn main() {
})
.map_err(|e| println!("error reading stdout; error = {:?}", e))
});
+ Ok(())
}
mod codec {
@@ -127,12 +129,13 @@ mod tcp {
use bytes::BytesMut;
use codec::Bytes;
+ use std::error::Error;
use std::io;
use std::net::SocketAddr;
pub fn connect(addr: &SocketAddr,
stdin: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>)
- -> Box<Stream<Item = BytesMut, Error = io::Error> + Send>
+ -> Result<Box<Stream<Item = BytesMut, Error = io::Error> + Send>, Box<Error>>
{
let tcp = TcpStream::connect(addr);
@@ -151,22 +154,24 @@ mod tcp {
// You'll also note that we *spawn* the work to read stdin and write it
// to the TCP stream. This is done to ensure that happens concurrently
// with us reading data from the stream.
- Box::new(tcp.map(move |stream| {
+ let stream = Box::new(tcp.map(move |stream| {
let (sink, stream) = Bytes.framed(stream).split();
tokio::spawn(stdin.forward(sink).then(|result| {
if let Err(e) = result {
- panic!("failed to write to socket: {}", e)
+ println!("failed to write to socket: {}", e)
}
Ok(())
}));
stream
- }).flatten_stream())
+ }).flatten_stream());
+ Ok(stream)
}
}
mod udp {
+ use std::error::Error;
use std::io;
use std::net::SocketAddr;
@@ -179,17 +184,19 @@ mod udp {
pub fn connect(&addr: &SocketAddr,
stdin: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>)
- -> Box<Stream<Item = BytesMut, Error = io::Error> + Send>
+ -> Result<Box<Stream<Item = BytesMut, Error = io::Error> + Send>, Box<Error>>
{
// We'll bind our UDP socket to a local IP/port, but for now we
// basically let the OS pick both of those.
let addr_to_bind = if addr.ip().is_ipv4() {
- "0.0.0.0:0".parse().unwrap()
+ "0.0.0.0:0".parse()?
} else {
- "[::]:0".parse().unwrap()
+ "[::]:0".parse()?
+ };
+ let udp = match UdpSocket::bind(&addr_to_bind) {
+ Ok(udp) => udp,
+ Err(_) => Err("failed to bind socket")?,
};
- let udp = UdpSocket::bind(&addr_to_bind)
- .expect("failed to bind socket");
// Like above with TCP we use an instance of `Bytes` codec to transform
// this UDP socket into a framed sink/stream which operates over
@@ -203,7 +210,7 @@ mod udp {
(chunk, addr)
}).forward(sink).then(|result| {
if let Err(e) = result {
- panic!("failed to write to socket: {}", e)
+ println!("failed to write to socket: {}", e)
}
Ok(())
});
@@ -218,10 +225,11 @@ mod udp {
}
});
- Box::new(future::lazy(|| {
+ let stream = Box::new(future::lazy(|| {
tokio::spawn(forward_stdin);
future::ok(receive)
- }).flatten_stream())
+ }).flatten_stream());
+ Ok(stream)
}
}
diff --git a/examples/echo-udp.rs b/examples/echo-udp.rs
index 89cc3d16..08a14563 100644
--- a/examples/echo-udp.rs
+++ b/examples/echo-udp.rs
@@ -50,12 +50,12 @@ impl Future for Server {
}
}
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
- let addr = addr.parse::<SocketAddr>().unwrap();
+ let addr = addr.parse::<SocketAddr>()?;
- let socket = UdpSocket::bind(&addr).unwrap();
- println!("Listening on: {}", socket.local_addr().unwrap());
+ let socket = UdpSocket::bind(&addr)?;
+ println!("Listening on: {}", socket.local_addr()?);
let server = Server {
socket: socket,
@@ -70,4 +70,5 @@ fn main() {
//
// `tokio::run` spawns the task on the Tokio runtime and starts running.
tokio::run(server.map_err(|e| println!("server error = {:?}", e)));
+ Ok(())
}
diff --git a/examples/echo.rs b/examples/echo.rs
index 92d65a90..f33247cb 100644
--- a/examples/echo.rs
+++ b/examples/echo.rs
@@ -30,19 +30,19 @@ use tokio::prelude::*;
use std::env;
use std::net::SocketAddr;
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
// Allow passing an address to listen on as the first argument of this
// program, but otherwise we'll just set up our TCP listener on
// 127.0.0.1:8080 for connections.
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
- let addr = addr.parse::<SocketAddr>().unwrap();
+ let addr = addr.parse::<SocketAddr>()?;
// Next up we create a TCP listener which will listen for incoming
// connections. This TCP listener is bound to the address we determined
// above and must be associated with an event loop, so we pass in a handle
// to our event loop. After the socket's created we inform that we're ready
// to go and start accepting connections.
- let socket = TcpListener::bind(&addr).unwrap();
+ let socket = TcpListener::bind(&addr)?;
println!("Listening on: {}", addr);
// Here we convert the `TcpListener` to a stream of incoming connections
@@ -111,4 +111,5 @@ fn main() {
// never completes (it just keeps accepting sockets), `tokio::run` blocks
// forever (until ctrl-c is pressed).
tokio::run(done);
+ Ok(())
}
diff --git a/examples/hello_world.rs b/examples/hello_world.rs
index c94ec53c..a05a8f22 100644
--- a/examples/hello_world.rs
+++ b/examples/hello_world.rs
@@ -19,8 +19,8 @@ use tokio::io;
use tokio::net::TcpStream;
use tokio::prelude::*;
-pub fn main() {
- let addr = "127.0.0.1:6142".parse().unwrap();
+pub fn main() -> Result<(), Box<std::error::Error>> {
+ let addr = "127.0.0.1:6142".parse()?;
// Open a TCP stream to the socket address.
//
@@ -52,4 +52,6 @@ pub fn main() {
println!("About to create the stream and write to it...");
tokio::run(client);
println!("Stream has been created and written to.");
+
+ Ok(())
}
diff --git a/examples/manual-runtime.rs b/examples/manual-runtime.rs
index 6cbb8cd4..8e3e1299 100644
--- a/examples/manual-runtime.rs
+++ b/examples/manual-runtime.rs
@@ -60,7 +60,7 @@ fn run<F: Future<Item = (), Error = ()>>(f: F) -> Result<(), IoError> {
Ok(())
}
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
run(future::lazy(|| {
// Here comes the application logic. It can spawn further tasks by tokio_current_thread::spawn().
// It also can use the default reactor and create timeouts.
@@ -82,5 +82,6 @@ fn main() {
// We can spawn on the default executor, which is also the local one.
tokio::executor::spawn(deadline);
Ok(())
- })).unwrap();
+ }))?;
+ Ok(())
}
diff --git a/examples/print_each_packet.rs b/examples/print_each_packet.rs
index 644d144c..864d94bd 100644
--- a/examples/print_each_packet.rs
+++ b/examples/print_each_packet.rs
@@ -65,19 +65,19 @@ use tokio::codec::Decoder;
use std::env;
use std::net::SocketAddr;
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
// Allow passing an address to listen on as the first argument of this
// program, but otherwise we'll just set up our TCP listener on
// 127.0.0.1:8080 for connections.
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
- let addr = addr.parse::<SocketAddr>().unwrap();
+ let addr = addr.parse::<SocketAddr>()?;
// Next up we create a TCP listener which will listen for incoming
// connections. This TCP listener is bound to the address we determined
// above and must be associated with an event loop, so we pass in a handle
// to our event loop. After the socket's created we inform that we're ready
// to go and start accepting connections.
- let socket = TcpListener::bind(&addr).unwrap();
+ let socket = TcpListener::bind(&addr)?;
println!("Listening on: {}", addr);
// Here we convert the `TcpListener` to a stream of incoming connections
@@ -146,4 +146,5 @@ fn main() {
// never completes (it just keeps accepting sockets), `tokio::run` blocks
// forever (until ctrl-c is pressed).
tokio::run(done);
+ Ok(())
}
diff --git a/examples/proxy.rs b/examples/proxy.rs
index bed8314a..1df115fd 100644
--- a/examples/proxy.rs
+++ b/examples/proxy.rs
@@ -33,15 +33,15 @@ use tokio::io::{copy, shutdown};
use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::*;
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
let listen_addr = env::args().nth(1).unwrap_or("127.0.0.1:8081".to_string());
- let listen_addr = listen_addr.parse::<SocketAddr>().unwrap();
+ let listen_addr = listen_addr.parse::<SocketAddr>()?;
let server_addr = env::args().nth(2).unwrap_or("127.0.0.1:8080".to_string());
- let server_addr = server_addr.parse::<SocketAddr>().unwrap();
+ let server_addr = server_addr.parse::<SocketAddr>()?;
// Create a TCP listener which will listen for incoming connections.
- let socket = TcpListener::bind(&listen_addr).unwrap();
+ let socket = TcpListener::bind(&listen_addr)?;
println!("Listening on: {}", listen_addr);
println!("Proxying to: {}", server_addr);
@@ -94,6 +94,7 @@ fn main() {
});
tokio::run(done);
+ Ok(())
}
// This is a custom type used to have a custom implementation of the
diff --git a/examples/tinydb.rs b/examples/tinydb.rs
index 134d01b1..702704d3 100644
--- a/examples/tinydb.rs
+++ b/examples/tinydb.rs
@@ -74,12 +74,12 @@ enum Response {
Error { msg: String },
}
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
// Parse the address we're going to run this server on
// and set up our TCP listener to accept connections.
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
- let addr = addr.parse::<SocketAddr>().unwrap();
- let listener = TcpListener::bind(&addr).expect("failed to bind");
+ let addr = addr.parse::<SocketAddr>()?;
+ let listener = TcpListener::bind(&addr).map_err(|_| "failed to bind")?;
println!("Listening on: {}", addr);
// Create the shared state of this server that will be shared amongst all
@@ -156,6 +156,7 @@ fn main() {
});
tokio::run(done);
+ Ok(())
}
impl Request {
diff --git a/examples/tinyhttp.rs b/examples/tinyhttp.rs
index 1e4f22bd..7a80d730 100644
--- a/examples/tinyhttp.rs
+++ b/examples/tinyhttp.rs
@@ -34,13 +34,13 @@ use bytes::BytesMut;
use http::header::HeaderValue;
use http::{Request, Response, StatusCode};
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
// Parse the arguments, bind the TCP socket we'll be listening to, spin up
// our worker threads, and start shipping sockets to those worker threads.
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
- let addr = addr.parse::<SocketAddr>().unwrap();
+ let addr = addr.parse::<SocketAddr>()?;
- let listener = TcpListener::bind(&addr).expect("failed to bind");
+ let listener = TcpListener::bind(&addr)?;
println!("Listening on: {}", addr);
tokio::run({
@@ -51,6 +51,7 @@ fn main() {
Ok(())
})
});
+ Ok(())
}
fn process(socket: TcpStream) {
@@ -84,28 +85,32 @@ fn process(socket: TcpStream) {
fn respond(req: Request<()>)
-> Box<Future<Item = Response<String>, Error = io::Error> + Send>
{
- let mut ret = Response::builder();
- let body = match req.uri().path() {
- "/plaintext" => {
- ret.header("Content-Type", "text/plain");
- "Hello, World!".to_string()
- }
- "/json" => {
- ret.header("Content-Type", "application/json");
+ let f = future::lazy(move || {
+ let mut response = Response::builder();
+ let body = match req.uri().path() {
+ "/plaintext" => {
+ response.header("Content-Type", "text/plain");
+ "Hello, World!".to_string()
+ }
+ "/json" => {
+ response.header("Content-Type", "application/json");
- #[derive(Serialize)]
- struct Message {
- message: &'static str,
+ #[derive(Serialize)]
+ struct Message {
+ message: &'static str,
+ }
+ serde_json::to_string(&Message { message: "Hello, World!" })?
}
- serde_json::to_string(&Message { message: "Hello, World!" })
- .unwrap()
- }
- _ => {
- ret.status(StatusCode::NOT_FOUND);
- String::new()
- }
- };
- Box::new(future::ok(ret.body(body).unwrap()))
+ _ => {
+ response.status(StatusCode::NOT_FOUND);
+ String::new()
+ }
+ };
+ let response = response.body(body).map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
+ Ok(response)
+ });
+
+ Box::new(f)
}
struct Http;
diff --git a/examples/udp-client.rs b/examples/udp-client.rs
index 3af7c3be..d2d4bc99 100644
--- a/examples/udp-client.rs
+++ b/examples/udp-client.rs
@@ -35,29 +35,27 @@ use std::net::SocketAddr;
use tokio::net::UdpSocket;
use tokio::prelude::*;
-fn get_stdin_data() -> Vec<u8> {
+fn get_stdin_data() -> Result<Vec<u8>, Box<std::error::Error>> {
let mut buf = Vec::new();
- stdin().read_to_end(&mut buf).unwrap();
- buf
+ stdin().read_to_end(&mut buf)?;
+ Ok(buf)
}
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
let remote_addr: SocketAddr = env::args()
.nth(1)
.unwrap_or("127.0.0.1:8080".into())
- .parse()
- .unwrap();
+ .parse()?;
// We use port 0 to let the operating system allocate an available port for us.
let local_addr: SocketAddr = if remote_addr.is_ipv4() {
"0.0.0.0:0"
} else {
"[::]:0"
- }.parse()
- .unwrap();
- let socket = UdpSocket::bind(&local_addr).unwrap();
+ }.parse()?;
+ let socket = UdpSocket::bind(&local_addr)?;
const MAX_DATAGRAM_SIZE: usize = 65_507;
- let processing = socket
- .send_dgram(get_stdin_data(), &remote_addr)
+ socket
+ .send_dgram(get_stdin_data()?, &remote_addr)
.and_then(|(socket, _)| socket.recv_dgram(vec![0u8; MAX_DATAGRAM_SIZE]))
.map(|(_, data, len, _)| {
println!(
@@ -66,9 +64,6 @@ fn main() {
String::from_utf8_lossy(&data[..len])
)
})
- .wait();
- match processing {
- Ok(_) => {}
- Err(e) => eprintln!("Encountered an error: {}", e),
- }
+ .wait()?;
+ Ok(())
}
diff --git a/examples/udp-codec.rs b/examples/udp-codec.rs
index b273a360..837266ac 100644
--- a/examples/udp-codec.rs
+++ b/examples/udp-codec.rs
@@ -19,15 +19,15 @@ use tokio::prelude::*;
use tokio::net::{UdpSocket, UdpFramed};
use tokio_codec::BytesCodec;
-fn main() {
+fn main() -> Result<(), Box<std::error::Error>> {
let _ = env_logger::init();
- let addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
+ let addr: SocketAddr = "127.0.0.1:0".parse()?;
// Bind both our sockets and then figure out what ports we got.
- let a = UdpSocket::bind(&addr).unwrap();
- let b = UdpSocket::bind(&addr).unwrap();
- let b_addr = b.local_addr().unwrap();
+ let a = UdpSocket::bind(&addr)?;
+ let b = UdpSocket::bind(&addr)?;
+ let b_addr = b.local_addr()?;
// We're parsing each socket with the `BytesCodec` included in `tokio_io`, and then we
// `split` each codec into the sink/stream halves.
@@ -61,4 +61,5 @@ fn main() {
.map(|_| ())
.map_err(|e| println!("error = {:?}", e))
});
+ Ok(())
}