RustBrock/Error Handling.md
2025-01-21 17:26:31 +00:00

3.1 KiB

Error Handing

This is a factor of life in software, Rust has a number of features for handling errors. One feature is that Rust requires you to acknowledge the possibility of an error and take some action beofre our code will compile.

This requirement ensures that errors are handled before the possiblity could arise

This can be split into two major categories

  • Recoverable - File a file not found, just need to report the problem to the user and retry the operation
  • Unrecoverable - A symptom of bugs, like trying to access a location beyond the end of an array. Need to immediately stop the program

Many languages dont distinguish between the two kinds of errors and handle them the same way using mechanisms such as exceptions

Rust does not have exceptions

Instead it has the type Result< T, E> for recoverable errors

It has the panc! macro to stop eecution when an unrecoverable error occurs

Unrecoverable Errors

Whne bad things happen in your code and nothing you can do nothing about it then Rust has the panc! macro

There are two ways to cause a panic:

  • by taking an action that causes the code to paic (like accessing an array past the end)
  • explicity calling panic! macro

By default these print a failure message, unwind, clean up the stack and then quit.

Using an environment variable you can also have Rust display the call stack when a panic occurs. This can make it easier to track down the source of the panic

When a call to panic! occurs the error message will be contained in the last two lines. The first line will contain our message and the second is when te source of this panic occured

example

fn main() {
    panic!("crash and burn");
}

This will output

thread 'main' panicked at src/main.rs:2:5:
crash and burn
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

This indicates that the panic occured in the file main.rs at the 2nd line on the 5th character

In this example it indicates that it is part of our source cdoe, looking there will show the panic! macro

In other cases the panic! call might be reported as someone else code where the panic! macro was called

You can also use the traceback functions of the panic call to figure ot the part of our code that caused the problem

To understand this an example will be used

fn main() {
    let v = vec![1, 2, 3];

    v[99];
}

Unwinding the Stack or Aborting in Response to a Panic

unwinding in rust means that it walks back up the stack and cleans up the data form each function it encounters.

However walking back and cleaning up is a lot of work

Rust also allows yo to choose the alternative of immediately aborting, which means ends the program without cleaning up

Memory that the program was using will thne be clean up by the OS

If yo need your project's resultant binary as small as possible you can switch from unwinfing to aborting upon a panic

This can be done by adding panic = 'abort' to the appropriate [profile] section in your Cargo.toml

example of this

[profile.release]
panic = 'abort'