From 0e5257e98c2a33a505602a2b5d45368599bda949 Mon Sep 17 00:00:00 2001 From: Jaroslaw Konik Date: Wed, 14 May 2025 14:43:40 +0200 Subject: [PATCH] handle errors --- ...cript_function_that_causes_runtime_error.rb | 3 +++ assets/tests/ruby/return_via_promise.rb | 9 +++++++++ src/lib.rs | 4 ++-- src/runtimes/ruby.rs | 18 ++++++++++++------ tests/tests.rs | 6 +++--- 5 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 assets/tests/ruby/call_script_function_that_causes_runtime_error.rb create mode 100644 assets/tests/ruby/return_via_promise.rb diff --git a/assets/tests/ruby/call_script_function_that_causes_runtime_error.rb b/assets/tests/ruby/call_script_function_that_causes_runtime_error.rb new file mode 100644 index 0000000..c9a193a --- /dev/null +++ b/assets/tests/ruby/call_script_function_that_causes_runtime_error.rb @@ -0,0 +1,3 @@ +def test_func + print("abc" + 5) +end diff --git a/assets/tests/ruby/return_via_promise.rb b/assets/tests/ruby/return_via_promise.rb new file mode 100644 index 0000000..51635ec --- /dev/null +++ b/assets/tests/ruby/return_via_promise.rb @@ -0,0 +1,9 @@ +STATE = { + 'x' => nil +} + +def test_func + rust_func.and_then do |x| + STATE['x'] = x + end +end diff --git a/src/lib.rs b/src/lib.rs index bf7e0d5..ceb7496 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -280,9 +280,9 @@ const ENTITY_VAR_NAME: &str = "entity"; #[derive(Error, Debug)] pub enum ScriptingError { #[error("script runtime error: {0}")] - RuntimeError(Box), + RuntimeError(Box), #[error("script compilation error: {0}")] - CompileError(Box), + CompileError(Box), #[error("no runtime resource present")] NoRuntimeResource, #[error("no settings resource present")] diff --git a/src/runtimes/ruby.rs b/src/runtimes/ruby.rs index d46c4ba..73eabd9 100644 --- a/src/runtimes/ruby.rs +++ b/src/runtimes/ruby.rs @@ -12,6 +12,7 @@ use std::{ thread::{self, JoinHandle}, }; +use anyhow::anyhow; use bevy::{ asset::Asset, ecs::{ @@ -19,6 +20,7 @@ use bevy::{ schedule::ScheduleLabel, }, reflect::TypePath, + tasks::futures_lite::io, }; use magnus::{function, method::ReturnValue, IntoValue, Ruby, TryConvert}; use magnus::{prelude::*, rb_sys::FromRawValue}; @@ -28,7 +30,7 @@ use serde::Deserialize; use crate::{ assets::GetExtensions, callback::{FromRuntimeValueWithEngine, IntoRuntimeValueWithEngine}, - FuncArgs, Runtime, + FuncArgs, Runtime, ScriptingError, }; #[derive(Resource)] @@ -263,8 +265,7 @@ impl Runtime for RubyRuntime { args: impl for<'a> crate::FuncArgs<'a, Self::Value, Self> + Send + 'static, ) -> Result { let name = name.to_string(); - Ok(self - .ruby_thread + self.ruby_thread .as_ref() .unwrap() .execute(Box::new(move |ruby| { @@ -273,9 +274,14 @@ impl Runtime for RubyRuntime { .into_iter() .map(|a| ruby.get_inner(a.0)) .collect(); - let _: magnus::Value = ruby.class_object().funcall(name, args.as_slice()).unwrap(); - RubyValue::nil(&ruby) - }))) + let return_value: magnus::Value = 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( diff --git a/tests/tests.rs b/tests/tests.rs index 4991357..676f75e 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -274,7 +274,7 @@ macro_rules! scripting_tests { } #[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(); app.add_scripting::<$runtime>(|_| {}); @@ -297,7 +297,7 @@ macro_rules! scripting_tests { } #[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(); app.add_scripting::<$runtime>(|_| {}); @@ -316,7 +316,7 @@ macro_rules! scripting_tests { } #[test] - fn test_promise() { + fn test_return_via_promise() { let mut app = build_test_app(); app.add_scripting::<$runtime>(|runtime| {