Rust errors: Difference between revisions
From wikinotes
(→Result) |
(→Result) |
||
Line 40: | Line 40: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{ expand | |||
| <code>match</code> the various cases | |||
| | |||
<syntaxhighlight lang="rust"> | <syntaxhighlight lang="rust"> | ||
let result = match is_one(2) { | let result = match is_one(2) { | ||
Line 48: | Line 51: | ||
println!("{}", result); | println!("{}", result); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
}} | |||
{{ expand | |||
| Panic if not successful | |||
| | |||
<syntaxhighlight lang="rust"> | <syntaxhighlight lang="rust"> | ||
// panic if error, otherwise return value | // panic if error, otherwise return value | ||
Line 59: | Line 66: | ||
.expect("an error occurred!") // <-- panic message | .expect("an error occurred!") // <-- panic message | ||
</syntaxhighlight> | </syntaxhighlight> | ||
}} | |||
{{ expand | |||
| Propagate the error if not successful | |||
| | |||
It's also fairly common that you want to delegate handling the error to the caller.<br> | |||
There is also syntactic sugar for this. | |||
The <code>?</code> operator returns with the <code>Err</code> if it errored.<br> | |||
You'll only need to provide the <code>Ok()</code> value. | |||
<syntaxhighlight lang="rust"> | |||
fn print_if_result_ok(r: Result<String, MyError>) -> Result<String, MyError> { | |||
let result = is_one(2)? // return Err() if err | |||
println!("success value: {}", result); | |||
Ok("success") | |||
} | |||
</syntaxhighlight> | |||
}} | |||
</blockquote><!-- Result --> | </blockquote><!-- Result --> |
Revision as of 18:27, 8 February 2023
Rust has two primary methods of handling errors.
panic!()
halts/exits the programResult
types are for handle-able errors
panic
- intended for halting application, not control flow
- have backtraces
panic!("tried to X but couldn't Y") // convert panic to result // (not intended for native rust code) let result = panic::catch_unwind(|| { panic!("oh no!"); });
Result
The result type is an enum, whose options
Ok, Err
have been merged into the global scope throughprelude
.Given this Result producing code:
struct MyError { value: isize } fn is_one(i: isize) -> Result<String, MyError> { if i == 1 { Ok("success".to_string()) } else { Err(MyError{value: i}) } }
match
the various cases
let result = match is_one(2) { Ok(x) => format!("horay: {}", x), Err(_) => panic!("an error occurred") }; println!("{}", result);Panic if not successful
// panic if error, otherwise return value let result = is_one(2) .unwrap() // panic with message if error, otherwise return value let result = is_one(2) .expect("an error occurred!") // <-- panic messagePropagate the error if not successful
It's also fairly common that you want to delegate handling the error to the caller.
There is also syntactic sugar for this.The
?
operator returns with theErr
if it errored.
You'll only need to provide theOk()
value.fn print_if_result_ok(r: Result<String, MyError>) -> Result<String, MyError> { let result = is_one(2)? // return Err() if err println!("success value: {}", result); Ok("success") }