Skip to content
Related Articles

Related Articles

Improve Article

Rust – Recoverable Errors

  • Last Updated : 21 Jul, 2021

An error is basically an unexpected behavior or event that may lead a program to produce undesired output or terminate abruptly. Errors are things that no one wants in their program. Recoverable errors are those that do not cause the program to terminate abruptly. Example- When we try to fetch a file that is not present or we do not have permission to open it.

Most language does not distinguish between the two errors and use an Exception class to overcome them while Rust uses a data type Result <R,T> to handle recoverable errors and panic! macro to stop the execution of the program in case of unrecoverable errors. Result<T,E> is an enum data type with two variants OK and Err which is defined something like this:-

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

T and E are generic type parameters where T represents the type of value that will be returned in a success case within the Ok variant, and E represents the type of error that will be returned in a failure case within the Err variant.

Rust




use std::fs::File;
  
fn main() {
   let f = File::open("gfg.txt");
    println!("{:?}",f);
}

Output



Err(Os { code: 2, kind: NotFound, message: "No such file or directory" })

Since the file gfg.txt was not there so the Err instance was returned by File. If the file gfg.txt had been found then an instance to the file would have been returned.

If a file is not found just like the above case then it will be better if we ask the user to check the file name, file location or to give the file specifications once more or whatever the situation demands.

Rust




use std::fs::File;
  
fn main() {
  
  // file doesn't exist
  let f = File::open("gfg.txt");
  
  match f {
     Ok(file)=> {
        println!("file found {:?}",file);
     },
     Err(_error)=> {
             
       // replace it with whatever you want to do if file is not found
        println!("file not found \n");   
     }
      }
  }

Output

file not found

In the above program, it basically matches the return type of the result and performs the task accordingly.

Let’s create our own errors according to business logic. Suppose we want to produce an error if a person below 18 years tries to apply for voter ID.

Rust




fn main(){
  
  let result = eligible(13);
  
  match result {
     Ok(age)=>{
        println!("Person eligible to vote with age={}",age);
     },
  
     Err(msg)=>{
        println!("{}",msg);
     }
  }
}
  
fn eligible(age:i32)->Result<i32,String> {
  
  if age>=18 {
     return Ok(age);
  
  } else {
     return Err("Not Eligible..Wait for some years".to_string());
  }
}

Output

Not Eligible..Wait for some years

If we want to abort the program after it encounters a recoverable error then we could use panic! macro and to simplify the process Rust provides two methods unwrap() and expect().

  • Unwrap()

Rust




use std::fs::File;
fn main() {
  
   let f = File::open("gfg.txt").unwrap();
  
}

Output

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value:
Os { code: 2, kind: NotFound, message: "No such file or directory" }', main.rs:17:14

The unwrap() calls the panic! macro in case of file not found while it returns the file handler instance if the file is found. Although unwrap() makes the program shorter but when there are too many unwrap() methods in our program then it becomes a bit confusing as to which unwrap() method is called the panic! macro. So we need something that can produce the customized message. In that case, expect() method comes to the rescue.

  • expect()

Rust




use std::fs::File;
  
fn main() {
   let f = File::open("hello.txt").expect("Failed to open gfg.txt");
}

Output:

thread 'main' panicked at 'Failed to open gfg.txt:
Os { code: 2, kind: NotFound, message: "No such file or directory" }', main.rs:17:14

We passed our message to panic! macro via the expect parameter.




My Personal Notes arrow_drop_up
Recommended Articles
Page :