Error Handling in Rust programming language
Tags: rust
Published: 2019-04-27 17:54:16

---
title: Error Handling in Rust programming language
published: true
description: Error Handling in Rust
tags: #rust #rustlang
---

![Alt text of image](https://cdn-images-1.medium.com/max/1200/1*y1BM50iNmvX1bcBLq5d5DA.jpeg)

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](https://doc.rust-lang.org/book/), Rust has one of the best documentations available.

Today we will be looking at [error handling](https://doc.rust-lang.org/1.30.0/book/second-edition/ch09-00-error-handling.html) 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](https://doc.rust-lang.org/std/option/index.html) and [Result](https://doc.rust-lang.org/std/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.

```rs
enum Result<T, E> {

 Ok(T),

 Err(E),

}
```

Now let’s see some examples.

First we will learn about **Option**

```rs
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**

```rs
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.


```rs
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 ❤❤