|
| 1 | +# panic::catch_unwind for exceptions |
| 2 | + |
| 3 | +## Description |
| 4 | + |
| 5 | +This antipattern arises when the method for catching (`panic::catch_unwind`) an |
| 6 | +unexpected problem (implementation bug) is used to handle an expected problem, |
| 7 | +such as a missing file. |
| 8 | + |
| 9 | +## Example |
| 10 | + |
| 11 | +```rust |
| 12 | +use std::io::prelude::*; |
| 13 | +use std::fs::File; |
| 14 | +use std::panic; |
| 15 | + |
| 16 | +fn main() { |
| 17 | + // panic::catch_unwind catches any panic that occurs within the |
| 18 | + // function passed to it |
| 19 | + let result = panic::catch_unwind(|| { |
| 20 | + let mut file_result = File::open("foo.txt"); |
| 21 | + file_result.unwrap(); // causes a panic if the file is not found |
| 22 | + }); |
| 23 | + |
| 24 | + // the program continues running despite the panic |
| 25 | + println!("potential error: {:?}", result); |
| 26 | + assert!(result.is_err()); |
| 27 | +} |
| 28 | +``` |
| 29 | + |
| 30 | + |
| 31 | +## Motivation |
| 32 | + |
| 33 | +In rust, there are two ways an operation can fail: An expected problem, like a |
| 34 | +file not being found, or a HTTP request timing out. Or, an unexpected problem, |
| 35 | +such as an index being out of bounds, or an assert!() failing. These are |
| 36 | +unexpected because they are bugs that should not happen. It would not make sense |
| 37 | +to handle an error for QuickSort returning an incorrectly unsorted array, as |
| 38 | +this should not happen. |
| 39 | + |
| 40 | +There are scenarios where using panic::catch_unwind is the correct choice, eg, a |
| 41 | +web server implementation wants to save an unwinding thread in order to send a |
| 42 | +valid response if the route for that request (as in: logic outside of the web server |
| 43 | +implementor's control) is producing a panic. |
| 44 | + |
| 45 | +Expected errors should not result in stack unwinding. Instead, expected errors |
| 46 | +should be handled through the Result and Option types. [The Rust Book's chapter |
| 47 | +on Error Handling](https://doc.rust-lang.org/book/error-handling.html) elaborates further on this. |
| 48 | + |
| 49 | +## See also |
| 50 | + |
| 51 | +[The Rust Book: Error Handling](https://doc.rust-lang.org/book/error-handling.html) |
| 52 | +[Rust 1.9 announcement, which contains a description of this antipattern](http://blog.rust-lang.org/2016/05/26/Rust-1.9.html) |
| 53 | +[Result documentation](http://doc.rust-lang.org/std/result/enum.Result.html) |
| 54 | +[panic::catch_unwind documentation](https://doc.rust-lang.org/std/panic/fn.catch_unwind.html) |
0 commit comments