Skip to main content

just_llm_client/tools/
error.rs

1use thiserror::Error;
2
3/// Registration errors emitted by [`ToolDispatcher`](super::ToolDispatcher).
4#[allow(missing_docs)]
5#[derive(Debug, Error)]
6pub enum ToolRegistrationError {
7    /// Attempted to register two tools with the same name.
8    #[error("duplicate tool name '{name}'")]
9    DuplicateTool { name: String },
10}
11
12impl ToolRegistrationError {
13    /// Creates a duplicate-tool registration error.
14    pub fn duplicate_tool(name: impl Into<String>) -> Self {
15        Self::DuplicateTool { name: name.into() }
16    }
17}
18
19/// Call-time errors emitted by [`ToolDispatcher`](super::ToolDispatcher).
20#[allow(missing_docs)]
21#[derive(Debug, Error)]
22pub enum ToolCallError {
23    /// Attempted to execute an unknown tool.
24    #[error("unknown tool '{name}'. available tools: {available}")]
25    UnknownTool { name: String, available: String },
26
27    /// Registered tool execution failed abnormally.
28    #[error("tool '{name}' execution failed: {source:#}")]
29    Execution {
30        name: String,
31        #[source]
32        source: anyhow::Error,
33    },
34}
35
36impl ToolCallError {
37    /// Creates an unknown-tool call error.
38    pub fn unknown_tool(
39        name: impl Into<String>,
40        available: impl IntoIterator<Item = impl AsRef<str>>,
41    ) -> Self {
42        let available = available
43            .into_iter()
44            .map(|name| name.as_ref().to_owned())
45            .collect::<Vec<_>>();
46        let available = if available.is_empty() {
47            "(none)".to_owned()
48        } else {
49            available.join(", ")
50        };
51
52        Self::UnknownTool {
53            name: name.into(),
54            available,
55        }
56    }
57
58    /// Creates a tool-execution error.
59    pub fn execution(name: impl Into<String>, source: anyhow::Error) -> Self {
60        Self::Execution {
61            name: name.into(),
62            source,
63        }
64    }
65}