Error Handling Flashcards
(29 cards)
What are two important types in rust, used for error handling? What are their possible variants?
Result (OK, Err) and Option (Some, None)
What is equivalent to: let first_inner = match first { Ok(inner) => inner, Err(_) => Person {name: "unknown",}, }
let first_inner = first.unwrap_or_default(); *default value should be defined
What is equivalent to: let first_inner = match first { Ok(inner) => inner, Err(_) => panic!("awh!!!"), };
let first_inner = first.expect(“awh!!!”);
What is equivalent to: let first_inner = first.unwrap_or_default(); *first is of type Result *Person is struct with one field named "name" and its default value is "unknown"
let first_inner = match first { Ok(inner) => inner, Err(_) => Person {name: "unknown",}, }
What is equivalent to: let first_inner = first.expect("awh!!!");
let first_inner = match first {
Ok(inner) => inner,
Err(_) => panic!(“awh!!!”),
};
What is equivalent to: let record = save_to_database(text)?; *Assuming save_to_database() returns Result type
let record = match save_to_database(text) { Ok(value) => value, Err(e) => return Err(e), };
What is equivalent to: let record = match save_to_database(text) { Ok(value) => value, Err(e) => return Err(e), };
let record = save_to_database(text)?;
Use old macro to get: let record = save_to_database(text)?;
let record = try!(save_to_database(text));
Where can we use the ‘?’ operator?
In the past, only for functions that returns Result type
In rust 1.22.0+, for function that returns Option type (excluding main and test functions)
In rust 1.26.0+, for main function that returns Result type.
In rust 1.28.0+, for test functions that returns Result type.
*In general for any type that implements std::ops::Try.
What is equivalent to:
let num = n.last()?;
Some(num + 5)
*Assuming n is of type &[i32]
let num = match n.last() { Some(num) => Some(num + 5), None => None, }; ***(I think it should be return None - need to make sure!!!)
What is equivalent to:
let num: i32 = “10”.parse().expect(“parsing failed”);
let num: i32 = match "10".parse() { Ok(inner) => inner, Err(_) => panic!("parsing failed"), }; *** is the panic! statement should be inside of { } and end with semicolon? like so: Err(_) => {panic!("parsing failed");}
Name two solutions to the problem of a function that might fail in multiple ways.
Solution 1: Returning a Box trait object
Solution 2: Defining a custom error type
What traits are needed to define a custom error type? What trait is need to be able to use the ? operator.
Error trait is needed to use custom error.
From trait is needed to use the ? operator.
What is the main downside of using Box strategy for handling multiple error types?
What should we use in order to overcome this issue?
Given a Box, one can’t inspect the error type in code, hence can’t handle different errors based on their type.
To over come the issue - use custom error type.
When is it ok to use ? operator in the following code
fn create_doc(name: &str) ->Result {
let file =
OpenOptions::new().write(true).create_new(true).open(name)?;
}
The From trait must be implemented: impl From for MyError { fn from(other: io::Error) -> Self { MyError::something(other) } } ... Enum MyError { something(io::Error), ...}
How can you shorten the generic type:
Result;
pub type Result = Result;
and you can right simply Result
How to enable backtrace capturing in rust?
running:
RUST_BACKTRACE=1 cargo run
Name three crates that are designated for error handling. Do they support: Display implementation, From conversions, Backtraces? What kind of Macro?
- quick-error (regular Macro, supports all except Backtraces)
- error-chain (regular Macro, supports all)
- failure (derive Macro supports all)
How do you test which variant of Result you have?
Using the methods: is_ok, is_err
How do you test which variant of Option you have?
Using the methods: is_some, is_none
Why is the following is an antipattern? if option_value.is_some() { let inner = option_value.unwrap(); println!("inner = {}", inner) } What is a better way to do it?
- The code indeed ensures that the unwrap() won’t panic, but it isn’t very clear.
- The code is also doing a redundant check of which variant the value is.
A better, more idiomatic option, will be:
if let Some(inner) = option_value {
println!(“inner = {}”, inner)
}
How can you convert a Result into an Option?
By using the ok method:
Ok(T).ok() converts to Some(T)
Err(E).ok() converts to None and discards the error value
How can you convert an Option into a Result?
By using the ok_or method.
Some(T).ok_or(err_value) converts to Ok(T)
None.ok_or(err_value) converts to Err(err_value)
*notice that we need to specify the error value.
How can you specify and use fallback (specific one) values for Option and Result types?
By using the unwrap_or method. For Result: Ok(T).unwrap_or(fallback) -> T Err(T).unwrap_or(fallback) -> fallback For Option: Some(T).unwrap_or(fallback) -> T None.unwrap_or(fallback) -> fallback