Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFP - Add try_ prefixed variants to rhai functions that can throw #21

Open
sphilipakis opened this issue Nov 13, 2024 · 0 comments
Open

Comments

@sphilipakis
Copy link

sphilipakis commented Nov 13, 2024

RFP: Add try_ prefixed variants to rhai functions that can throw

Overview

Some functions available to the rhai scripts may throw on failure. For example:

// will throw
let content = file::load("some_non_existant_file");

// will throw if no internet
let content = web::get("some_url");

The proposal is to define try_ variants of these functions that return null instead of throwing an exception. This enables the use of the ?? null coalescing operator for elegant fallback handling:

// won't fail, returns "default content" if file not found
let content = file::try_load("some_non_existant_file") ?? "default content";

// won't fail, returns "default content" if request fails
let content = web::try_get("some_url") ?? "default content";

Motivation

  • Provides a more ergonomic way to handle potential failures in rhai scripts
  • Enables cleaner fallback patterns using the ?? operator
  • Reduces need for try/catch blocks which can make scripts harder to read
  • Follows common programming patterns where try_ prefixed functions return optional values

Proposed Implementation

Similar to how the devai module functions are implemented, we can wrap the throwing functions with a try_ variant that catches errors and returns null. Example implementation pattern:

// In the respective rhai module files
fn try_load(path: &str) -> RhaiResult {
    match file::load(path) {
        Ok(content) => Ok(content.into()),
        Err(_) => Ok(Dynamic::NULL),
    }
}

fn try_get(url: &str) -> RhaiResult {
    match web::get(url) {
        Ok(content) => Ok(content.into()),
        Err(_) => Ok(Dynamic::NULL),
    }
}

Example Usage

// File operations with fallbacks
let content = file::try_load("config.json") ?? "{}";
let backup = file::try_load("backup.txt") ?? "";

// Web requests with defaults
let api_data = web::try_get("https://api.example.com/data") ?? "[]";
let user_info = web::try_get("https://api.example.com/user") ?? "{}";

// Chaining multiple attempts
let config = 
    file::try_load("config.local.json") ??
    file::try_load("config.json") ??
    "{}";

Future Considerations

  • Consider adding try_ variants for other functions that can throw
  • Evaluate if certain functions should only have try_ versions
  • Consider adding result type information to function documentation
  • May want to standardize error logging/handling for try_ variants
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant