Rust errors: Difference between revisions

From wikinotes
Line 75: Line 75:


The <code>?</code> operator returns with the <code>Err</code> if it errored.<br>
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.
You'll only need to provide the <code>Ok()</code> value.<br>
(note you can also pass an Option and receive an Option in the same manner)


<syntaxhighlight lang="rust">
<syntaxhighlight lang="rust">
fn print_if_result_ok(r: Result<String, MyError>) -> Result<String, MyError> {
fn print_if_result_ok(i: isize) -> Result<String, MyError> {
     let result = is_one(2)? // return Err() if err
     let result = is_one(i)?                 // return Err() if err
     println!("success value: {}", result);
     println!("success value: {}", result); // unwraps result, and you know it is Ok() now
     Ok("success")
     Ok("success")
}
}
</syntaxhighlight>
</syntaxhighlight>


}}
}}
</blockquote><!-- Result -->
</blockquote><!-- Result -->

Revision as of 18:44, 8 February 2023

Rust has two primary methods of handling errors.

  • panic!() halts/exits the program
  • Result 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 through prelude.

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 message

Propagate 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 the Err if it errored.
You'll only need to provide the Ok() 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")
}