Skip to content

Commit 9b1a45c

Browse files
liranringeltobz
authored andcommitted
tests: handle errors properly in examples (tokio-rs#748)
1 parent 477fa55 commit 9b1a45c

19 files changed

+143
-118
lines changed

examples/chat-combinator.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ use std::env;
3434
use std::io::{BufReader};
3535
use std::sync::{Arc, Mutex};
3636

37-
fn main() {
37+
fn main() -> Result<(), Box<std::error::Error>> {
3838
// Create the TCP listener we'll accept connections on.
3939
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
40-
let addr = addr.parse().unwrap();
40+
let addr = addr.parse()?;
4141

42-
let socket = TcpListener::bind(&addr).unwrap();
42+
let socket = TcpListener::bind(&addr)?;
4343
println!("Listening on: {}", addr);
4444

4545
// This is running on the Tokio runtime, so it will be multi-threaded. The
@@ -49,10 +49,10 @@ fn main() {
4949
// The server task asynchronously iterates over and processes each incoming
5050
// connection.
5151
let srv = socket.incoming()
52-
.map_err(|e| println!("failed to accept socket; error = {:?}", e))
52+
.map_err(|e| {println!("failed to accept socket; error = {:?}", e); e})
5353
.for_each(move |stream| {
5454
// The client's socket address
55-
let addr = stream.peer_addr().unwrap();
55+
let addr = stream.peer_addr()?;
5656

5757
println!("New Connection: {}", addr);
5858

@@ -143,8 +143,10 @@ fn main() {
143143
}));
144144

145145
Ok(())
146-
});
146+
})
147+
.map_err(|err| println!("error occurred: {:?}", err));
147148

148149
// execute server
149150
tokio::run(srv);
151+
Ok(())
150152
}

examples/chat.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -426,20 +426,20 @@ fn process(socket: TcpStream, state: Arc<Mutex<Shared>>) {
426426
tokio::spawn(connection);
427427
}
428428

429-
pub fn main() {
429+
pub fn main() -> Result<(), Box<std::error::Error>> {
430430
// Create the shared state. This is how all the peers communicate.
431431
//
432432
// The server task will hold a handle to this. For every new client, the
433433
// `state` handle is cloned and passed into the task that processes the
434434
// client connection.
435435
let state = Arc::new(Mutex::new(Shared::new()));
436436

437-
let addr = "127.0.0.1:6142".parse().unwrap();
437+
let addr = "127.0.0.1:6142".parse()?;
438438

439439
// Bind a TCP listener to the socket address.
440440
//
441441
// Note that this is the Tokio TcpListener, which is fully async.
442-
let listener = TcpListener::bind(&addr).unwrap();
442+
let listener = TcpListener::bind(&addr)?;
443443

444444
// The server task asynchronously iterates over and processes each
445445
// incoming connection.
@@ -471,4 +471,5 @@ pub fn main() {
471471
// In our example, we have not defined a shutdown strategy, so this will
472472
// block until `ctrl-c` is pressed at the terminal.
473473
tokio::run(server);
474+
Ok(())
474475
}

examples/connect.rs

+28-20
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use std::thread;
2929
use tokio::prelude::*;
3030
use futures::sync::mpsc;
3131

32-
fn main() {
32+
fn main() -> Result<(), Box<std::error::Error>> {
3333
// Determine if we're going to run in TCP or UDP mode
3434
let mut args = env::args().skip(1).collect::<Vec<_>>();
3535
let tcp = match args.iter().position(|a| a == "--udp") {
@@ -41,26 +41,27 @@ fn main() {
4141
};
4242

4343
// Parse what address we're going to connect to
44-
let addr = args.first().unwrap_or_else(|| {
45-
panic!("this program requires at least one argument")
46-
});
47-
let addr = addr.parse::<SocketAddr>().unwrap();
44+
let addr = match args.first() {
45+
Some(addr) => addr,
46+
None => Err("this program requires at least one argument")?,
47+
};
48+
let addr = addr.parse::<SocketAddr>()?;
4849

4950
// Right now Tokio doesn't support a handle to stdin running on the event
5051
// loop, so we farm out that work to a separate thread. This thread will
5152
// read data (with blocking I/O) from stdin and then send it to the event
5253
// loop over a standard futures channel.
5354
let (stdin_tx, stdin_rx) = mpsc::channel(0);
5455
thread::spawn(|| read_stdin(stdin_tx));
55-
let stdin_rx = stdin_rx.map_err(|_| panic!()); // errors not possible on rx
56+
let stdin_rx = stdin_rx.map_err(|_| panic!("errors not possible on rx"));
5657

5758
// Now that we've got our stdin read we either set up our TCP connection or
5859
// our UDP connection to get a stream of bytes we're going to emit to
5960
// stdout.
6061
let stdout = if tcp {
61-
tcp::connect(&addr, Box::new(stdin_rx))
62+
tcp::connect(&addr, Box::new(stdin_rx))?
6263
} else {
63-
udp::connect(&addr, Box::new(stdin_rx))
64+
udp::connect(&addr, Box::new(stdin_rx))?
6465
};
6566

6667
// And now with our stream of bytes to write to stdout, we execute that in
@@ -77,6 +78,7 @@ fn main() {
7778
})
7879
.map_err(|e| println!("error reading stdout; error = {:?}", e))
7980
});
81+
Ok(())
8082
}
8183

8284
mod codec {
@@ -127,12 +129,13 @@ mod tcp {
127129
use bytes::BytesMut;
128130
use codec::Bytes;
129131

132+
use std::error::Error;
130133
use std::io;
131134
use std::net::SocketAddr;
132135

133136
pub fn connect(addr: &SocketAddr,
134137
stdin: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>)
135-
-> Box<Stream<Item = BytesMut, Error = io::Error> + Send>
138+
-> Result<Box<Stream<Item = BytesMut, Error = io::Error> + Send>, Box<Error>>
136139
{
137140
let tcp = TcpStream::connect(addr);
138141

@@ -151,22 +154,24 @@ mod tcp {
151154
// You'll also note that we *spawn* the work to read stdin and write it
152155
// to the TCP stream. This is done to ensure that happens concurrently
153156
// with us reading data from the stream.
154-
Box::new(tcp.map(move |stream| {
157+
let stream = Box::new(tcp.map(move |stream| {
155158
let (sink, stream) = Bytes.framed(stream).split();
156159

157160
tokio::spawn(stdin.forward(sink).then(|result| {
158161
if let Err(e) = result {
159-
panic!("failed to write to socket: {}", e)
162+
println!("failed to write to socket: {}", e)
160163
}
161164
Ok(())
162165
}));
163166

164167
stream
165-
}).flatten_stream())
168+
}).flatten_stream());
169+
Ok(stream)
166170
}
167171
}
168172

169173
mod udp {
174+
use std::error::Error;
170175
use std::io;
171176
use std::net::SocketAddr;
172177

@@ -179,17 +184,19 @@ mod udp {
179184

180185
pub fn connect(&addr: &SocketAddr,
181186
stdin: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>)
182-
-> Box<Stream<Item = BytesMut, Error = io::Error> + Send>
187+
-> Result<Box<Stream<Item = BytesMut, Error = io::Error> + Send>, Box<Error>>
183188
{
184189
// We'll bind our UDP socket to a local IP/port, but for now we
185190
// basically let the OS pick both of those.
186191
let addr_to_bind = if addr.ip().is_ipv4() {
187-
"0.0.0.0:0".parse().unwrap()
192+
"0.0.0.0:0".parse()?
188193
} else {
189-
"[::]:0".parse().unwrap()
194+
"[::]:0".parse()?
195+
};
196+
let udp = match UdpSocket::bind(&addr_to_bind) {
197+
Ok(udp) => udp,
198+
Err(_) => Err("failed to bind socket")?,
190199
};
191-
let udp = UdpSocket::bind(&addr_to_bind)
192-
.expect("failed to bind socket");
193200

194201
// Like above with TCP we use an instance of `Bytes` codec to transform
195202
// this UDP socket into a framed sink/stream which operates over
@@ -203,7 +210,7 @@ mod udp {
203210
(chunk, addr)
204211
}).forward(sink).then(|result| {
205212
if let Err(e) = result {
206-
panic!("failed to write to socket: {}", e)
213+
println!("failed to write to socket: {}", e)
207214
}
208215
Ok(())
209216
});
@@ -218,10 +225,11 @@ mod udp {
218225
}
219226
});
220227

221-
Box::new(future::lazy(|| {
228+
let stream = Box::new(future::lazy(|| {
222229
tokio::spawn(forward_stdin);
223230
future::ok(receive)
224-
}).flatten_stream())
231+
}).flatten_stream());
232+
Ok(stream)
225233
}
226234
}
227235

examples/echo-udp.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ impl Future for Server {
5050
}
5151
}
5252

53-
fn main() {
53+
fn main() -> Result<(), Box<std::error::Error>> {
5454
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
55-
let addr = addr.parse::<SocketAddr>().unwrap();
55+
let addr = addr.parse::<SocketAddr>()?;
5656

57-
let socket = UdpSocket::bind(&addr).unwrap();
58-
println!("Listening on: {}", socket.local_addr().unwrap());
57+
let socket = UdpSocket::bind(&addr)?;
58+
println!("Listening on: {}", socket.local_addr()?);
5959

6060
let server = Server {
6161
socket: socket,
@@ -70,4 +70,5 @@ fn main() {
7070
//
7171
// `tokio::run` spawns the task on the Tokio runtime and starts running.
7272
tokio::run(server.map_err(|e| println!("server error = {:?}", e)));
73+
Ok(())
7374
}

examples/echo.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@ use tokio::prelude::*;
3030
use std::env;
3131
use std::net::SocketAddr;
3232

33-
fn main() {
33+
fn main() -> Result<(), Box<std::error::Error>> {
3434
// Allow passing an address to listen on as the first argument of this
3535
// program, but otherwise we'll just set up our TCP listener on
3636
// 127.0.0.1:8080 for connections.
3737
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
38-
let addr = addr.parse::<SocketAddr>().unwrap();
38+
let addr = addr.parse::<SocketAddr>()?;
3939

4040
// Next up we create a TCP listener which will listen for incoming
4141
// connections. This TCP listener is bound to the address we determined
4242
// above and must be associated with an event loop, so we pass in a handle
4343
// to our event loop. After the socket's created we inform that we're ready
4444
// to go and start accepting connections.
45-
let socket = TcpListener::bind(&addr).unwrap();
45+
let socket = TcpListener::bind(&addr)?;
4646
println!("Listening on: {}", addr);
4747

4848
// Here we convert the `TcpListener` to a stream of incoming connections
@@ -111,4 +111,5 @@ fn main() {
111111
// never completes (it just keeps accepting sockets), `tokio::run` blocks
112112
// forever (until ctrl-c is pressed).
113113
tokio::run(done);
114+
Ok(())
114115
}

examples/hello_world.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use tokio::io;
1919
use tokio::net::TcpStream;
2020
use tokio::prelude::*;
2121

22-
pub fn main() {
23-
let addr = "127.0.0.1:6142".parse().unwrap();
22+
pub fn main() -> Result<(), Box<std::error::Error>> {
23+
let addr = "127.0.0.1:6142".parse()?;
2424

2525
// Open a TCP stream to the socket address.
2626
//
@@ -52,4 +52,6 @@ pub fn main() {
5252
println!("About to create the stream and write to it...");
5353
tokio::run(client);
5454
println!("Stream has been created and written to.");
55+
56+
Ok(())
5557
}

examples/manual-runtime.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fn run<F: Future<Item = (), Error = ()>>(f: F) -> Result<(), IoError> {
6060
Ok(())
6161
}
6262

63-
fn main() {
63+
fn main() -> Result<(), Box<std::error::Error>> {
6464
run(future::lazy(|| {
6565
// Here comes the application logic. It can spawn further tasks by tokio_current_thread::spawn().
6666
// It also can use the default reactor and create timeouts.
@@ -82,5 +82,6 @@ fn main() {
8282
// We can spawn on the default executor, which is also the local one.
8383
tokio::executor::spawn(deadline);
8484
Ok(())
85-
})).unwrap();
85+
}))?;
86+
Ok(())
8687
}

examples/print_each_packet.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,19 @@ use tokio::codec::Decoder;
6565
use std::env;
6666
use std::net::SocketAddr;
6767

68-
fn main() {
68+
fn main() -> Result<(), Box<std::error::Error>> {
6969
// Allow passing an address to listen on as the first argument of this
7070
// program, but otherwise we'll just set up our TCP listener on
7171
// 127.0.0.1:8080 for connections.
7272
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
73-
let addr = addr.parse::<SocketAddr>().unwrap();
73+
let addr = addr.parse::<SocketAddr>()?;
7474

7575
// Next up we create a TCP listener which will listen for incoming
7676
// connections. This TCP listener is bound to the address we determined
7777
// above and must be associated with an event loop, so we pass in a handle
7878
// to our event loop. After the socket's created we inform that we're ready
7979
// to go and start accepting connections.
80-
let socket = TcpListener::bind(&addr).unwrap();
80+
let socket = TcpListener::bind(&addr)?;
8181
println!("Listening on: {}", addr);
8282

8383
// Here we convert the `TcpListener` to a stream of incoming connections
@@ -146,4 +146,5 @@ fn main() {
146146
// never completes (it just keeps accepting sockets), `tokio::run` blocks
147147
// forever (until ctrl-c is pressed).
148148
tokio::run(done);
149+
Ok(())
149150
}

examples/proxy.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ use tokio::io::{copy, shutdown};
3333
use tokio::net::{TcpListener, TcpStream};
3434
use tokio::prelude::*;
3535

36-
fn main() {
36+
fn main() -> Result<(), Box<std::error::Error>> {
3737
let listen_addr = env::args().nth(1).unwrap_or("127.0.0.1:8081".to_string());
38-
let listen_addr = listen_addr.parse::<SocketAddr>().unwrap();
38+
let listen_addr = listen_addr.parse::<SocketAddr>()?;
3939

4040
let server_addr = env::args().nth(2).unwrap_or("127.0.0.1:8080".to_string());
41-
let server_addr = server_addr.parse::<SocketAddr>().unwrap();
41+
let server_addr = server_addr.parse::<SocketAddr>()?;
4242

4343
// Create a TCP listener which will listen for incoming connections.
44-
let socket = TcpListener::bind(&listen_addr).unwrap();
44+
let socket = TcpListener::bind(&listen_addr)?;
4545
println!("Listening on: {}", listen_addr);
4646
println!("Proxying to: {}", server_addr);
4747

@@ -94,6 +94,7 @@ fn main() {
9494
});
9595

9696
tokio::run(done);
97+
Ok(())
9798
}
9899

99100
// This is a custom type used to have a custom implementation of the

examples/tinydb.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ enum Response {
7474
Error { msg: String },
7575
}
7676

77-
fn main() {
77+
fn main() -> Result<(), Box<std::error::Error>> {
7878
// Parse the address we're going to run this server on
7979
// and set up our TCP listener to accept connections.
8080
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
81-
let addr = addr.parse::<SocketAddr>().unwrap();
82-
let listener = TcpListener::bind(&addr).expect("failed to bind");
81+
let addr = addr.parse::<SocketAddr>()?;
82+
let listener = TcpListener::bind(&addr).map_err(|_| "failed to bind")?;
8383
println!("Listening on: {}", addr);
8484

8585
// Create the shared state of this server that will be shared amongst all
@@ -156,6 +156,7 @@ fn main() {
156156
});
157157

158158
tokio::run(done);
159+
Ok(())
159160
}
160161

161162
impl Request {

0 commit comments

Comments
 (0)