add backtrace

This commit is contained in:
Jaroslaw Konik 2025-05-26 07:00:00 +02:00
parent b339283901
commit c763dd06d1
3 changed files with 33 additions and 8 deletions

View file

@ -294,8 +294,8 @@ const ENTITY_VAR_NAME: &str = "entity";
/// An error that can occur when internal [ScriptingPlugin] systems are being executed /// An error that can occur when internal [ScriptingPlugin] systems are being executed
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum ScriptingError { pub enum ScriptingError {
#[error("script runtime error: {0}")] #[error("script runtime error: {0}\nscript backtrace:\n{1}")]
RuntimeError(Box<dyn std::error::Error + Send>), RuntimeError(String, String),
#[error("script compilation error: {0}")] #[error("script compilation error: {0}")]
CompileError(Box<dyn std::error::Error + Send>), CompileError(Box<dyn std::error::Error + Send>),
#[error("no runtime resource present")] #[error("no runtime resource present")]

View file

@ -1,3 +1,4 @@
// TODO: use funcall_public?
use std::{ use std::{
collections::HashMap, collections::HashMap,
ffi::CString, ffi::CString,
@ -5,7 +6,7 @@ use std::{
thread::{self, JoinHandle}, thread::{self, JoinHandle},
}; };
use ::magnus::value::Opaque; use ::magnus::{error::IntoError, typed_data::Inspect, value::Opaque};
use anyhow::anyhow; use anyhow::anyhow;
use bevy::{ use bevy::{
asset::Asset, asset::Asset,
@ -20,7 +21,7 @@ use magnus::{
value::{Lazy, ReprValue}, value::{Lazy, ReprValue},
}; };
use magnus::{method, prelude::*}; use magnus::{method, prelude::*};
use rb_sys::{VALUE, ruby_init_stack}; use rb_sys::{VALUE, rb_backtrace, rb_make_backtrace, ruby_init_stack};
use serde::Deserialize; use serde::Deserialize;
use crate::{ use crate::{
@ -223,7 +224,19 @@ impl TryConvert for BevyVec3 {
impl From<magnus::Error> for ScriptingError { impl From<magnus::Error> for ScriptingError {
fn from(value: magnus::Error) -> Self { fn from(value: magnus::Error) -> Self {
ScriptingError::RuntimeError(anyhow!(value.to_string()).into()) // TODO: DRY
ScriptingError::RuntimeError(
value.inspect(),
value
.value()
.unwrap()
.funcall::<_, _, magnus::RArray>("backtrace", ()) // TODO: is there an API for this
// somehwere
.unwrap()
.to_vec::<String>()
.unwrap()
.join("\n"),
)
} }
} }
@ -374,8 +387,20 @@ impl Runtime for RubyRuntime {
var.ivar_set("_current", BevyEntity(entity)) var.ivar_set("_current", BevyEntity(entity))
.expect("Failed to set current entity handle"); .expect("Failed to set current entity handle");
ruby.eval::<magnus::value::Value>(&script) unsafe {
.map_err(|e| ScriptingError::RuntimeError(anyhow!(e.to_string()).into()))?; ruby.eval::<magnus::value::Value>(&script).map_err(|e| {
ScriptingError::RuntimeError(
e.inspect(),
e.value()
.unwrap()
.funcall::<_, _, magnus::RArray>("backtrace", ())
.unwrap()
.to_vec::<String>()
.unwrap()
.join("\n"),
)
})?;
}
var.ivar_set("_current", ruby.qnil().as_value()) var.ivar_set("_current", ruby.qnil().as_value())
.expect("Failed to unset current entity handle"); .expect("Failed to unset current entity handle");

View file

@ -52,7 +52,7 @@ pub(crate) fn process_new_scripts<R: Runtime>(
let path = asset_server let path = asset_server
.get_path(&script_component.script) .get_path(&script_component.script)
.unwrap_or_default(); .unwrap_or_default();
tracing::error!("error running script {} {:?}", path, e); tracing::error!("error running script {} {}", path, e);
} }
} }
} }