Skip to main content

synaptic_tools/
handle_error.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4use serde_json::{json, Value};
5use synaptic_core::{SynapticError, Tool};
6
7/// A tool wrapper that catches errors and returns them as string values
8/// instead of propagating them.
9pub struct HandleErrorTool {
10    inner: Arc<dyn Tool>,
11    handler: Option<Box<dyn Fn(SynapticError) -> String + Send + Sync>>,
12}
13
14impl HandleErrorTool {
15    /// Wrap a tool with the default error handler (returns `error.to_string()`).
16    pub fn new(inner: Arc<dyn Tool>) -> Self {
17        Self {
18            inner,
19            handler: None,
20        }
21    }
22
23    /// Wrap a tool with a custom error handler function.
24    pub fn with_handler(
25        inner: Arc<dyn Tool>,
26        handler: impl Fn(SynapticError) -> String + Send + Sync + 'static,
27    ) -> Self {
28        Self {
29            inner,
30            handler: Some(Box::new(handler)),
31        }
32    }
33}
34
35#[async_trait]
36impl Tool for HandleErrorTool {
37    fn name(&self) -> &'static str {
38        self.inner.name()
39    }
40
41    fn description(&self) -> &'static str {
42        self.inner.description()
43    }
44
45    async fn call(&self, args: Value) -> Result<Value, SynapticError> {
46        match self.inner.call(args).await {
47            Ok(value) => Ok(value),
48            Err(err) => {
49                let error_string = match &self.handler {
50                    Some(handler) => handler(err),
51                    None => err.to_string(),
52                };
53                Ok(json!(error_string))
54            }
55        }
56    }
57}