This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/rhai_engine/rhaibook/rust/fallible.md
2025-04-03 09:18:05 +02:00

1.7 KiB

Register a Fallible Rust Function

{{#include ../links.md}}


A lot of times it is not necessary to register fallible functions.

Simply have the function returns [`Dynamic`].
Upon error, return [`()`] which is idiomatic in Rhai.

See [here](dynamic-return.md) for more details.

If a function is fallible (i.e. it returns a Result<_, _>), it can also be registered with via Engine::register_fn.

The function must return Result<T, Box<EvalAltResult>> where T is any clonable type.

In other words, the error type must be Box<EvalAltResult>. It is Boxed in order to reduce the size of the Result type since the error path is rarely hit.

use rhai::{Engine, EvalAltResult};

// Function that may fail - the error type must be 'Box<EvalAltResult>'
fn safe_divide(x: i64, y: i64) -> Result<i64, Box<EvalAltResult>> {
    if y == 0 {
        // Return an error if y is zero
        Err("Division by zero!".into())         // shortcut to create Box<EvalAltResult::ErrorRuntime>
    } else {
        Ok(x / y)
    }
}

let mut engine = Engine::new();

engine.register_fn("divide", safe_divide);

if let Err(error) = engine.eval::<i64>("divide(40, 0)") {
    println!("Error: {error:?}");               // prints ErrorRuntime("Division by zero detected!", (1, 1)")
}

`Box<EvalAltResult>` implements `From<&str>` and `From<String>` etc.
and the error text gets converted into `Box<EvalAltResult::ErrorRuntime>`.

The error values are `Box`-ed in order to reduce memory footprint of the error path,
which should be hit rarely.