Prevent deserializing panic

I've defined Location as:

#[derive(Serialize, Deserialize, Debug)]
struct Location {
    unique_id: String,
    lat: f64,
    lon: f64,
    speed: f64
}

And receive data from server, which is deserialized as:

let deserialize: Location = serde_json::from_str(&msg).expect("error");
println!("id = {:?}", deserialize);

If the received data can not be deserialized to Location, the system is panic, I need it to give an error only, without being paniced!!

If you don't want it to panic, then don't call .expect("error"), since that method panics if the Result returned by from_str is an Err.

I tried unwrap() but it paniced as well.

let deserialize: Location = serde_json::from_str(&msg).unwrap()

you can match on the Result from from_str and handle the Err case gracefully,

let deserialize: Location = match serde_json::from_str(&msg) {
    Ok(deserialize) => deserialize,
    Err(msg) => {
        // handle error here
    }
};

println!("id = {:?}", deserialize);

or

match serde_json::from_str::<Location>(&msg) {
    Ok(deserialize) => {
        println!("id = {:?}", deserialize);
    },
    Err(msg) => {
        // handle error here
    }
}

Thanks @RustyYato, this one did it perfectly:

And in a simpler way, as:

let deserialize = if let Ok(deserialize) = serde_json::from_str::<Location>(&msg) {
        println!("id = {:?}", deserialize.unique_id);
};

While with this one:

I was forced to return a Location with the error msg, to be:

let deserialize: Location = match serde_json::from_str(&msg){  
     Ok(deserialize) => deserialize,
     Err(msg) => {  Location {
                    unique_id: "".to_string(),
                    lat: 0.0,
                    lon: 0.0,
                    speed: 0.0
                }}
};

Note that let deserialize will always be assigned (), which may not be what you want, and the other way was just more explicit about this and forced you to make a new Location.

You don't have to make a new location in the Err branch of the match if you return early either with return, panic or similar control structures.

Thanks for coming back, for my current needs, the Ok(deserialize) is returning Location, and was able to manage my requirement within this scope, will be digging for the Err handling for improvement if required.

Appreciate your support.

Yes, that is all fine but look a bit to the left of the red circle and you will see let deserialize: () = ... which is likely not what you intended.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.