Errors

Errors in Rust are nothing but logics or syntaxes which are illegal and causes an interruption in the normal working of the program.

There are two different types of errors, which are:

  • Rcoverable Errors : This kind of errors can be be handled by the compiler or by the user. And thus, the program execution can flow normally, after the neccesary steps are taken to over-come the error.
  • Non-recoverabe Errors : This kind of errors can be handled by the user, which means that the user can not recover from the error. There are no ways with the help of which one can recover from the errors. And so, the program execution will stop in the error.

This has to be noted that, in other programming languages there are methods where we can use exceptions for handling errors. But in Rust, there are no such facility. Rust handles errors in a different way.

  • For recoverable errors, it returns an enum - Result<T,E>.
  • For non-recoverable errors, it will call the macro panic!().

Non Recoverable Errors

This kind of errors can be handled by the user, which means that the user can not recover from the error. When this kind of errors occurs, then the macro panic! is automatically involked by the Rust compiler and the program execution stops.

It may be noted that the macro can also be called from the user's side also.

Program to show the use of the macro panic!()
fn main() {
   panic!("Hello");
   }

In the above program output, we are have intentionally invoked the macro panic()! to see how the program execution stops.

Program Output :

thread 'main' panicked at 'Hello', rust-error-panic.rs:2:4
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

In the next example, we shall seen how an error will automatically call the macro panic!(). Here, we shall refer to an array index which is not present.

Program which abort the program(macro panic!() is called in the background automatically)

fn main() {
   let a = [1,2,3];
   a[4]; 
}

In the above program we have declared an array whose size of 3. This array has index starting from 0 to 2. Now when we tried to print the element from an index 4, which is not present, we are creating an error for the program flow and it is non-recoverable. Therefore, the macro panic()! is called to abort the program.

Program Output :

error: index out of bounds: the len is 3 but the index is 4
 --> rust-error-panic-calling.rs:3:4
  |
3 |    a[4];
  |    ^^^^
  |
  = note: #[deny(const_err)] on by default

error: aborting due to previous error
Using panic!() intentionally

This can be explained by considering the example below, where we use the macro panic!(), if the program flow is transferred in an else block of an if-else program.

fn main() {
    let number = 123;
    if number == 123 {
      println!("Number is same");
      }
      else {
        panic!("Number is not same. Panic is invoked");
      }
    }

Program Output :

thread 'main' panicked at 'Number is not same. Panic is invoked', rust-error-panic-invoke.rs:7:9
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

Recoverable Errors

Recoverable Errors are those errors which can be handled by the compiler. When this kind of error occurs, then the enum - Result <T,E>.

The enum Result <T, E> has two variants- T and E which are generic parameters. If in case, there is no erros then the variant T will be returned. Otherwise, the variant E will be returned.

Syntax :

enum Result<T,E> {
   OK(T),
   Err(E)
}

Program to search for a file

use std::fs::File;
fn main() {
  let file = File::open("my_pic01.jpg");
  match file {
    Ok(file) => {
        println!("file found {:?}", file);
      },
      Err(err) => {
        println!("file not found {:?}", err);
      }
  }
  println!("Hello! The program is still in flow.The error was handled properly");
}

In the above program we are willing to search for a file, which is not present inside the directory. And thus it is an error. Now the way to handle the error is to execute the Err part, and so that the error is handled and then the program flows normally.

Program Output :

file not found
Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }
Hello! The program is still in flow.The error was handled properly

unwrap() & expect()

unwrap()

The function unwrap() returns a panic if an operation fails along with printing the default error message. Otherwise, it will return an the actual result.

A program to check whether a number is even






unwrap() & expect()

unwrap()

The function unwrap() returns a panic if an operation fails along with printing the default error message. Otherwise, it will return an the actual result.

A program to check whether a number is even

fn main() {
  let result = check(8).unwrap();
  println!("Our check returned a {} result", result);
}
fn check(no: i32) - > Result < bool, bool > {
  if no % 2 == 0 {
    return Ok(true);
  } else {
    return Err(false);
  }
}

In the above program, we have concatenated the function unwrap(), with the function in operation check(). The function check(), returns an enum which has two default variants- OK and Err. When the check functions returns a true, that is when the number is even, then the OK part is executed and the keyword true is returned.

On the otherhand, when the check() function returns a false, then the macro unwrap() is automatically invoked to print the error message.

Program Output :

Case1 : When the number is even (TRUE case)

rust-error-unwrap-true

Program Output :

Case 1: When the number is not even (FALSE case)

thread 'main' panicked at 'called `Result::unwrap()` on
an `Err` value: false', src\libcore\result.rs:997:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
expect()

Using the function expect(), we can generate custom message for an error. This is helpful, because the compiler generated messages are somewhat very technical and may not be always understood by everyone.

A program to check whether an integer is even (FALSE Case)

fn main() {
  let result = check(81).expect("Error, this is a custom error message");
  println!("Our check returned a {} result", result);
  println!("Hello, there was no error. Let us continue..");
}
fn check(no: i32) -> Result < bool, bool > {
  if no % 2 == 0 {
    return Ok(true);
  } else {
    return Err(false);
  }
}

Program Out (When the function check() returns a false)

C:\Users\HP\checker\src>rust-error-expect
thread 'main' panicked at 'Error, this is a custom error message: false', src\libcore\result.rs:997:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions