Search code examples
rustrust-rocketreqwest

How can I fix my error 'thread 'rocket-worker-thread' panicked at 'called `Option::unwrap()` on a `None` value', src\main.rs:25:44'?


I'm coding a basic video streaming website, and am having trouble parsing json into rust. When I attempt to access the page 'http://127.0.0.1:8000/genres' I get a 500 response and in the console it says


GET /genres text/html:
   >> Matched: (genres) GET /genres
thread 'rocket-worker-thread' panicked at 'called `Option::unwrap()` on a `None` value', src\main.rs:25:44
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
   >> Handler genres panicked.

My code is:

#[macro_use] extern crate rocket;
extern crate reqwest;
extern crate serde;
extern crate serde_json;

use rocket::*;
use serde::{Deserialize, Serialize};
use serde_json::{Value};

#[derive(Serialize, Deserialize, Debug)]
struct Genre {
    genre: String
}

#[get("/genres")]
async fn genres() -> String {
    let response = match reqwest::get("http://34.88.173.79/myflix/genres").await {
        Ok(response) => response,
        Err(e) => return format!("Error: {}", e),
    };
    
    let json_string = response.text().await.unwrap();
    let json: Value = serde_json::from_str(&json_string).unwrap();

    let genres = json["genres"].as_array().unwrap();
    let mut html = String::new();
    for genre in genres {
        html.push_str(&format!("<h1>{}</h1>", genre));
    }
    html
}

#[get("/")]
fn index() -> &'static str {
    "Hello, world!"
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![index, genres])
}

and my cargo.toml is:

[package]
name = "dev_ops_webapp"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rocket = "0.5.0-rc.2"
reqwest = "0.11.13"
serde = "1.0.151"
serde_json = "1.0.90"
futures = "0.3"
tokio = { version = "1.12.0", features = ["full"] }

I know that it's probably not the best solution but I just can't figure it out! Any help given will be amazing.


Solution

  • You misread the format of the response. You're getting an array of objects which have a "genre" key. Not an object which has a "genres" key with an array of strings.

    You can replace your parsing with this:

    let json: Value = serde_json::from_str(&json_string).unwrap();
    
    for genre in json.as_array().unwrap() {
        html.push_str(&format!("<h1>{}</h1>", genre.as_str().unwrap()));
    }