handle errors

This commit is contained in:
Jaroslaw Konik 2025-05-14 14:43:40 +02:00
parent d97096bc9f
commit 0e5257e98c
5 changed files with 29 additions and 11 deletions

View file

@ -0,0 +1,3 @@
def test_func
print("abc" + 5)
end

View file

@ -0,0 +1,9 @@
STATE = {
'x' => nil
}
def test_func
rust_func.and_then do |x|
STATE['x'] = x
end
end

View file

@ -280,9 +280,9 @@ const ENTITY_VAR_NAME: &str = "entity";
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum ScriptingError { pub enum ScriptingError {
#[error("script runtime error: {0}")] #[error("script runtime error: {0}")]
RuntimeError(Box<dyn std::error::Error>), RuntimeError(Box<dyn std::error::Error + Send>),
#[error("script compilation error: {0}")] #[error("script compilation error: {0}")]
CompileError(Box<dyn std::error::Error>), CompileError(Box<dyn std::error::Error + Send>),
#[error("no runtime resource present")] #[error("no runtime resource present")]
NoRuntimeResource, NoRuntimeResource,
#[error("no settings resource present")] #[error("no settings resource present")]

View file

@ -12,6 +12,7 @@ use std::{
thread::{self, JoinHandle}, thread::{self, JoinHandle},
}; };
use anyhow::anyhow;
use bevy::{ use bevy::{
asset::Asset, asset::Asset,
ecs::{ ecs::{
@ -19,6 +20,7 @@ use bevy::{
schedule::ScheduleLabel, schedule::ScheduleLabel,
}, },
reflect::TypePath, reflect::TypePath,
tasks::futures_lite::io,
}; };
use magnus::{function, method::ReturnValue, IntoValue, Ruby, TryConvert}; use magnus::{function, method::ReturnValue, IntoValue, Ruby, TryConvert};
use magnus::{prelude::*, rb_sys::FromRawValue}; use magnus::{prelude::*, rb_sys::FromRawValue};
@ -28,7 +30,7 @@ use serde::Deserialize;
use crate::{ use crate::{
assets::GetExtensions, assets::GetExtensions,
callback::{FromRuntimeValueWithEngine, IntoRuntimeValueWithEngine}, callback::{FromRuntimeValueWithEngine, IntoRuntimeValueWithEngine},
FuncArgs, Runtime, FuncArgs, Runtime, ScriptingError,
}; };
#[derive(Resource)] #[derive(Resource)]
@ -263,8 +265,7 @@ impl Runtime for RubyRuntime {
args: impl for<'a> crate::FuncArgs<'a, Self::Value, Self> + Send + 'static, args: impl for<'a> crate::FuncArgs<'a, Self::Value, Self> + Send + 'static,
) -> Result<Self::Value, crate::ScriptingError> { ) -> Result<Self::Value, crate::ScriptingError> {
let name = name.to_string(); let name = name.to_string();
Ok(self self.ruby_thread
.ruby_thread
.as_ref() .as_ref()
.unwrap() .unwrap()
.execute(Box::new(move |ruby| { .execute(Box::new(move |ruby| {
@ -273,9 +274,14 @@ impl Runtime for RubyRuntime {
.into_iter() .into_iter()
.map(|a| ruby.get_inner(a.0)) .map(|a| ruby.get_inner(a.0))
.collect(); .collect();
let _: magnus::Value = ruby.class_object().funcall(name, args.as_slice()).unwrap(); let return_value: magnus::Value = ruby
RubyValue::nil(&ruby) .class_object()
}))) .funcall(name, args.as_slice())
.map_err(|e| {
ScriptingError::RuntimeError(Box::new(io::Error::other(e.to_string())))
})?;
Ok(RubyValue::new(return_value))
}))
} }
fn call_fn_from_value( fn call_fn_from_value(

View file

@ -274,7 +274,7 @@ macro_rules! scripting_tests {
} }
#[test] #[test]
fn test_call_script_function_that_does_not_exist() { fn test_call_script_function_that_causes_runtime_error() {
let mut app = build_test_app(); let mut app = build_test_app();
app.add_scripting::<$runtime>(|_| {}); app.add_scripting::<$runtime>(|_| {});
@ -297,7 +297,7 @@ macro_rules! scripting_tests {
} }
#[test] #[test]
fn test_script_function_gets_called_from_rust_without_params() { fn test_script_function_gets_called_from_rust() {
let mut app = build_test_app(); let mut app = build_test_app();
app.add_scripting::<$runtime>(|_| {}); app.add_scripting::<$runtime>(|_| {});
@ -316,7 +316,7 @@ macro_rules! scripting_tests {
} }
#[test] #[test]
fn test_promise() { fn test_return_via_promise() {
let mut app = build_test_app(); let mut app = build_test_app();
app.add_scripting::<$runtime>(|runtime| { app.add_scripting::<$runtime>(|runtime| {