From 18c5c3fd34ceb8a1631f7766b69e407cf92e1a09 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 15 May 2026 21:54:11 +0800 Subject: Add panic catch for program execution --- mingling_core/src/program/error.rs | 22 ++++++++++++++++++++++ mingling_core/src/program/exec/error.rs | 5 ++++- mingling_core/src/program/hook.rs | 24 +++++++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 mingling_core/src/program/error.rs (limited to 'mingling_core/src/program') diff --git a/mingling_core/src/program/error.rs b/mingling_core/src/program/error.rs new file mode 100644 index 0000000..5e92a42 --- /dev/null +++ b/mingling_core/src/program/error.rs @@ -0,0 +1,22 @@ +use std::any::Any; +use std::fmt; +use thiserror::Error; + +/// Error type returned when a panic occurs during execution. +#[derive(Error)] +#[error("execution panicked: {payload:?}")] +pub struct ProgramPanic { + pub payload: Box, +} + +impl ProgramPanic { + pub fn new(payload: Box) -> Self { + ProgramPanic { payload } + } +} + +impl fmt::Debug for ProgramPanic { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.payload) + } +} diff --git a/mingling_core/src/program/exec/error.rs b/mingling_core/src/program/exec/error.rs index b4ff378..2d806dc 100644 --- a/mingling_core/src/program/exec/error.rs +++ b/mingling_core/src/program/exec/error.rs @@ -1,4 +1,4 @@ -use crate::error::ChainProcessError; +use crate::error::{ChainProcessError, ProgramPanic}; #[derive(thiserror::Error, Debug)] pub enum ProgramExecuteError { @@ -8,6 +8,9 @@ pub enum ProgramExecuteError { #[error("No Renderer (`{0}`) Found")] RendererNotFound(String), + #[error("Panic: {0:?}")] + Panic(#[from] ProgramPanic), + #[error("Other error: {0}")] Other(String), } diff --git a/mingling_core/src/program/hook.rs b/mingling_core/src/program/hook.rs index afc253c..080c00f 100644 --- a/mingling_core/src/program/hook.rs +++ b/mingling_core/src/program/hook.rs @@ -1,6 +1,6 @@ use std::any::Any; -use crate::{AnyOutput, Program, ProgramCollect, RenderResult}; +use crate::{AnyOutput, Program, ProgramCollect, RenderResult, error::ProgramPanic}; #[derive(Default)] pub struct ProgramHook @@ -30,6 +30,9 @@ where /// Executes before the program ends pub finish: Option i32>, + + /// Executes when the program panics + pub exec_panic: Option, } impl Program @@ -126,6 +129,18 @@ where } } + pub(crate) fn run_hook_exec_panic(&self, panic_info: &ProgramPanic) { + if !self.user_context.run_hook { + return; + } + + for hook in &self.hooks { + if let Some(exec_panic) = hook.exec_panic { + exec_panic(panic_info) + } + } + } + pub(crate) fn run_hook_finish(&self) -> i32 { if !self.user_context.run_hook { return 0; @@ -159,6 +174,7 @@ where pre_render: None, post_render: None, finish: None, + exec_panic: None, } } @@ -209,4 +225,10 @@ where let _ = self.finish.insert(handler); self } + + /// Sets the handler for the `exec_panic` event. + pub fn on_exec_panic(mut self, handler: fn(&ProgramPanic)) -> Self { + let _ = self.exec_panic.insert(handler); + self + } } -- cgit