How should I handle f64 division by zero panic elegantly?

Hi! Thanks for taking the time to read my question. I am writing a reverse polish notation calculator web app using Wasm. The Vue "frontend" handles the state of the stack for calculation. Any calculator operations are passed to Rust through Wasm and handled there. The main purpose of this project is learning Wasm and running up against problems I haven't seen before. Here's one:

The stack on the Vue side is [7.0, 9.99, 0.0] and the user clicks the division button. Vue pops 0.0 and 9.99 off the stack and calls the operate function in Rust with the arguments 9.99, 0.0, and /.

The operate function should return a Result<f64, String>. I am trying to do the math using f64 so the calculator can be very precise (though maybe this is a mistake). Here is the operate function in a form that would crash badly:

#[wasm-bindgen]
pub fn operate(a: f64, b: f64, operation: String) -> Result<f64, String> {
    match &operation[..]  {
        "+" => Ok(a + b),
        "-" => Ok(a - b),
        "*" => Ok(a * b),
        "/" => Ok(a / b),
        _ => Err(format!(
            "Operation string `{}` does not match any allowed operation (+, -, *, /)",
            &operation[..]
        )),
    }
}

The a / b will panic. I'm not so sure what will happen next with Wasm, but I bet it's not good. I want to handle this panic, and return an Err to Vue, perhaps with a nice warning about zero division, so the user understands their mistake, but doesn't feel too bad about it.

What I have done so far is replace Ok(a / b) with divide(a, b) where divide is

fn divide(a: f64, b: f64) -> Result<f64, String> {
    /// Preemptively catch the division by zero panic case.
    /// See documentation for [Div](https://doc.rust-lang.org/std/ops/trait.Div.html)
    match b {
        0.0 => Err(String::from("Division by zero is not ok, but don't feel bad. I know you didn't mean it.")),
        _ => Ok(a / b),
    }
}

But, while ok for now, matching on a float is not going to be ok in Rust for much longer. How best should I catch the error thrown zero division occurs, so I can pass the error back to Vue?

Division by zero does not panic for f64 or f32.

assert!((0.0_f32 / 0.0).is_nan());
assert!((0.0_f64 / 0.0).is_nan());
2 Likes

Oh, thank you! I made some bad assumptions it looks like. Thanks for taking the time to answer :slight_smile: