Error Handling in Rust programming language
sai umesh
Posted on April 27, 2019
If you are following stack overflow developer survey, you might have seen Rust as most loved programming language 2 years in a row. Rust is probably most fascinating programming language I’ve seen, and I completely agree with survey.
Having said that, Learning Rust is not easy, learning curve is very high, and If you are coming from languages like JavaScript like me, it will be very challenging journey but, this tough road is worth it.
If you are very new to learning Rust, I strongly suggest starting with their docs, Rust has one of the best documentations available.
Today we will be looking at error handling in rust.
If you are coming from languages like JavaScript, the way JS and Rust handles errors are poles apart. Enough of talk let’s start with some code 😋😋.
Before coding anything we need to learn Option and Result in Rust.
Option in Rust represents an optional value: every Option is either Some and contains a value, or None, and does not. Option types are very common in Rust code, as they have a number of uses.
Result in Rust is the type used for returning and propagating errors. It is an enum with the variants, Ok(T), representing success and containing a value, and Err(E), representing error and containing an error value.
enum Result<T, E> {
Ok(T),
Err(E),
}
Now let’s see some examples.
First we will learn about Option
fn main() {
// first let's define vector/array of numbers
let numbers = vec![1, 2, 4];
// now let's try to read value from vector
let index_one = numbers[1];
println!("value at index {}", index_one);
// now let's try to read 10th index which doesn't exists
// since Rust doesn't have neither null nor try/catch to handle error
// so we will take leverage of **Option**
// un comment below two line to check error 😢😢
// let out_of_index = numbers[10];
// println!("this will throw error {}", out_of_index);
// above code would result in following error
// thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 10'
// rust has very interesting way to handle these errors
// we will take advantage of Option and get method from
// vector to handle these kind of errors
// get method of vector returns **Option** enum
// Option will have two properties Some and None
// let's see how to read/catch error
match numbers.get(10) {
Some(value) => println!("Hello {}", value),
None => println!("Yo!! out of bound error")
}
// now let's see how to read value from it
let result = match numbers.get(10) {
Some(value) => value,
None => &-1 // defaulting to -1
};
println!("result is {}", result);
// as you can see above code works well but,
// we can improve code by taking advantage of Result
}
Now, let’s improve above code little bit
fn read_from_vec(input: &Vec<i32>, index: usize) -> Result<i32, &'static str> {
return match input.get(index) {
Some(value) => Ok(*value),
None => Err("Out of bound exception")
}
}
fn main() {
// now lets take same example and improve error handling
let numbers = vec![1, 2, 4];
let result = read_from_vec(&numbers, 2);
// now since result is of type **Result** we can handle this in multiple ways
if result.is_ok() {
println!("got the value {}", result.unwrap());
} else {
println!("yo!! got the error {:?}", result.unwrap_err());
}
// above code works but there's an even better way to handle the same
match result {
Ok(data) => println!("indexed value {}", data),
Err(err) => println!("error is {}", err)
}
Now let’s see a Generic use case of reading file.
use std::io;
use std::io::Read;
use std::fs::File;
fn read_from_file(file_path: &'static str) -> Result<String, io::Error> {
let mut file_data = String::new();
// now let's try to read file
// here ? is for handling errors
// if there's an error it will break program and returns error
// let mut f = File::open(file_path)?;
// f.read_to_string(&mut file_data)?;
// return Ok(file_data);
// we can simplify above code by writing
File::open(file_path)?.read_to_string(&mut file_data)?;
Ok(file_data)
}
fn main() {
// now let's see more generic use cases
// for error handling
let file_path = "hello.txt";
match read_from_file(file_path) {
Ok(data) => println!("file data {}", data),
Err(err) => println!("err {}", err)
};
}
I’m still learning Rust, Hopefully I made some sense about Error handling in Rust Language. If you have any doubts or suggestions you can contact me on my twitter. until then, I will see you in other Post. Peace ❤❤
Posted on April 27, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.