converge_provider/tools/
error.rs1use thiserror::Error;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum ToolErrorKind {
11 NotFound,
12 InvalidArguments,
13 ExecutionFailed,
14 ConnectionFailed,
15 ServerError,
16 Timeout,
17 ValidationFailed,
18 PermissionDenied,
19 UnsupportedSource,
20}
21
22impl ToolErrorKind {
23 #[must_use]
24 pub const fn is_retryable(&self) -> bool {
25 matches!(
26 self,
27 Self::ConnectionFailed | Self::ServerError | Self::Timeout
28 )
29 }
30}
31
32#[derive(Debug, Error)]
34#[error("{kind:?}: {message}")]
35pub struct ToolError {
36 pub kind: ToolErrorKind,
37 pub message: String,
38 #[source]
39 pub source: Option<Box<dyn std::error::Error + Send + Sync>>,
40}
41
42impl ToolError {
43 #[must_use]
44 pub fn new(kind: ToolErrorKind, message: impl Into<String>) -> Self {
45 Self {
46 kind,
47 message: message.into(),
48 source: None,
49 }
50 }
51
52 #[must_use]
53 pub fn not_found(tool_name: impl Into<String>) -> Self {
54 let name = tool_name.into();
55 Self::new(ToolErrorKind::NotFound, format!("Tool not found: {name}"))
56 }
57
58 #[must_use]
59 pub fn invalid_arguments(message: impl Into<String>) -> Self {
60 Self::new(ToolErrorKind::InvalidArguments, message)
61 }
62
63 #[must_use]
64 pub fn connection_failed(message: impl Into<String>) -> Self {
65 Self::new(ToolErrorKind::ConnectionFailed, message)
66 }
67
68 #[must_use]
69 pub fn validation_failed(message: impl Into<String>) -> Self {
70 Self::new(ToolErrorKind::ValidationFailed, message)
71 }
72
73 #[must_use]
74 pub fn unsupported_source(source_type: impl Into<String>) -> Self {
75 let source = source_type.into();
76 Self::new(
77 ToolErrorKind::UnsupportedSource,
78 format!("Unsupported tool source: {source}"),
79 )
80 }
81
82 #[must_use]
83 pub fn is_retryable(&self) -> bool {
84 self.kind.is_retryable()
85 }
86}