Rust errors: Difference between revisions
From wikinotes
(→Result) |
(→Result) |
||
Line 21: | Line 21: | ||
= Result = | = Result = | ||
<blockquote> | <blockquote> | ||
The result type is an enum, whose options <code>Ok, Err</code> have been merged into the global scope through <code>prelude</code>. | The result type is an enum, whose options <code>Ok, Err</code> have been merged into the global scope through <code>prelude</code>.<br> | ||
<code>Err</code> can be any type, but the standard library predominantly uses <code>std::error::Error</code> concretions. | |||
Given this Result producing code: | Given this Result producing code: |
Revision as of 03:08, 9 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
.
Err
can be any type, but the standard library predominantly usesstd::error::Error
concretions.Given this Result producing code:
use std::error::Error; use std::fmt; // A custom std::error::Error impl #[derive(Debug)] struct MyError {} impl Error for MyError{} impl fmt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "i borked because...") } } // a result type fn is_one(i: isize) -> Result<String, MyError> { if i == 1 { Ok("success".to_string()) } else { Err(MyError{}) } }
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.
(note you can also pass an Option and receive an Option in the same manner)fn print_if_result_ok(i: isize) -> Result<String, MyError> { let result = is_one(i)? // return Err() if err println!("success value: {}", result); // unwraps result, and you know it is Ok() now Ok("success") }