How to do it...

  1. Inside the bin folder, create a new file called errors.rs.
  2. Add the following code and run it with cargo run --bin errors:
1   extern crate futures;
2   
3   use futures::prelude::*;
4   use futures::executor::block_on;
5   use futures::stream;
6   use futures::task::Context;
7   use futures::future::{FutureResult, err};
  1. After that, let's add our structures and implementations:
9   struct MyFuture {}
10  impl MyFuture {
11    fn new() -> Self {
12      MyFuture {}
13    }
14  }
15  
16  fn map_error_example() -> FutureResult<(), &'static str> {
17    err::<(), &'static str>("map_error has occurred")
18  }
19  
20  fn err_into_example() -> FutureResult<(), u8> {
21    err::<(), u8>(1)
22  }
23  
24  fn or_else_example() -> FutureResult<(), &'static str> {
25    err::<(), &'static str>("or_else error has occurred")
26  }
27  
28  impl Future for MyFuture {
29    type Item = ();
30    type Error = &'static str;
31  
32    fn poll(&mut self, _cx: &mut Context) -> Poll<Self::Item, Self::Error> {
33      Err("A generic error goes here")
34    }
35  }
36  
37  struct FuturePanic {}
38  
39  impl Future for FuturePanic {
40    type Item = ();
41    type Error = ();
42  
43    fn poll(&mut self, _cx: &mut Context) -> Poll<Self::Item, 
Self::Error> { 44 panic!("It seems like there was a major issue with
catch_unwind_example") 45 } 46 }
  1. After that, let's add our generic error handling functions/examples:
48  fn using_recover() {
49    let f = MyFuture::new();
50  
51    let f_recover = f.recover::<Never, _>(|err| {
52      println!("An error has occurred: {}", err);
53      ()
54    });
55  
56    block_on(f_recover).unwrap();
57  }
58  
59  fn map_error() {
60    let map_fn = |err| format!("map_error_example: {}", err);
61  
62    if let Err(e) = block_on(map_error_example().map_err(map_fn)) 
{ 63 println!("block_on error: {}", e) 64 } 65 } 66 67 fn err_into() { 68 if let Err(e) = block_on(err_into_example().err_into::()) { 69 println!("block_on error code: {:?}", e) 70 } 71 } 72 73 fn or_else() { 74 if let Err(e) = block_on(or_else_example() 75 .or_else(|_| Err("changed or_else's error message"))) { 76 println!("block_on error: {}", e) 77 } 78 }
  1. And now for our panic functions:
80  fn catch_unwind() {
81    let f = FuturePanic {};
82  
83    if let Err(e) = block_on(f.catch_unwind()) {
84      let err = e.downcast::<&'static str>().unwrap();
85      println!("block_on error: {:?}", err)
86    }
87  }
88  
89  fn stream_panics() {
90    let stream_ok = stream::iter_ok::<_, bool>(vec![Some(1),  
Some(7), None, Some(20)]); 91 // We panic on "None" values in order to simulate a stream
that panics 92 let stream_map = stream_ok.map(|o| o.unwrap()); 93 94 // We can use catch_unwind() for catching panics 95 let stream = stream_map.catch_unwind().then(|r| Ok::<_, ()>
(r)); 96 let stream_results: Vec<_> =
block_on(stream.collect()).unwrap(); 97 98 // Here we can use the partition() function to separate the Ok
and Err values 99 let (oks, errs): (Vec<_>, Vec<_>) =
stream_results.into_iter().partition(Result::is_ok); 100 let ok_values: Vec<_> =
oks.into_iter().map(Result::unwrap).collect(); 101 let err_values: Vec<_> =
errs.into_iter().map(Result::unwrap_err).collect(); 102 103 println!("Panic's Ok values: {:?}", ok_values); 104 println!("Panic's Err values: {:?}", err_values); 105 }
  1. And finally, our main function:
107 fn main() {
108   println!("using_recover():");
109   using_recover();
110 
111   println!("
map_error():");
112   map_error();
113 
114   println!("
err_into():");
115   err_into();
116 
117   println!("
or_else():");
118   or_else();
119 
120   println!("
catch_unwind():");
121   catch_unwind();
122 
123   println!("
stream_panics():");
124   stream_panics();
125 }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.12.34