Reqwest json handle empty response

So I have a page with JSON data for multiple devices, I retrieve the JSON and it gets "mapped" to the corresponding Struct, worked good but sometimes there will be no JSON available for a given device (this is to be expected) and since I'm using unwrap() rust will panic when this happens.

called Option::unwrap() on a None value

What would be the correct way to approach this? I'm thinking of using match but I'm unsure.

pub async fn get_alerts_device(device: u8) -> Result<Vec<MyAlerts>, reqwest::Error> {
    let client = reqwest::Client::new();
    let res = client
        .get("https://example.com/json-page")
        .send()
        .await?;

    let end: Device = res.json().await.unwrap();

    let deviceMap = end
        .device
        .get_key_value(format!("device-{}", device).as_str())
        .unwrap()
        .1;

    Ok(antennaMap.clone())

}

I've included the code in the function I'm mentioning so i hope it doesn't clutter to much. But ofcourse the focus lies with res.json().await.unwrap();

Thank you for your time and patience, I'm re-reading the book chapter on error handling as we speak!

There is no universally correct way to approach this, only a context-specific one. What do you want to happen? I.e. what does it mean (from the perspective of your program) when no JSON is returned from the remote location? Is it an error? Should None cases be handled by the caller? Should these cases be treated silently, e.g. by returning an empty vector?

2 Likes

Indeed, you can use either of match, if let ... else or let ... else in your case.

Depending on what you want to happen, you can e.g. default to an empty Vec of alerts:

pub async fn get_alerts_device(device: u8) -> Result<Vec<MyAlerts>, reqwest::Error> {
    let client = reqwest::Client::new();
    let res = client
        .get("https://example.com/json-page")
        .send()
        .await?;

    let Ok(end) = res.json::<Device>().await else {
        return Ok(Default::default());
    };

    let deviceMap = end
        .device
        .get_key_value(format!("device-{}", device).as_str())
        .unwrap()
        .1;

    Ok(antennaMap.clone())

}
2 Likes

What i'd want is is that the user gets a simple message informing that there is no data available, f.e: "No alerts for device n".

In this case I'd probably do what conqp did in the snippet above and return an empty vector, if no JSON was found. At the call site you can then handle how you want to inform the user about the fact that no alerts were found for the device, by checking whether the vector is empty or not.

2 Likes

OK I can work with this! very helpful, thank you so much :slight_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.