1use thiserror::Error;
7
8use entelix_core::error::Error;
9
10pub type ToolResult<T> = std::result::Result<T, ToolError>;
12
13#[derive(Debug, Error)]
15#[non_exhaustive]
16pub enum ToolError {
17 #[error("invalid input: {0}")]
19 InvalidInput(String),
20
21 #[error("host '{host}' not on the allowlist")]
23 HostBlocked {
24 host: String,
26 },
27
28 #[error("unsupported URL scheme '{scheme}': only http/https are allowed")]
30 UnsupportedScheme {
31 scheme: String,
33 },
34
35 #[error("method '{method}' not allowed by this tool")]
37 MethodBlocked {
38 method: String,
40 },
41
42 #[error("response body exceeded {limit_bytes} bytes")]
44 BodyTooLarge {
45 limit_bytes: usize,
47 },
48
49 #[error("network: {message}")]
53 Network {
54 message: String,
56 #[source]
58 source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
59 },
60
61 #[error("configuration: {message}")]
65 Config {
66 message: String,
68 #[source]
70 source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
71 },
72
73 #[error("calculator: {0}")]
75 Calculator(String),
76
77 #[error(transparent)]
79 Serde(#[from] serde_json::Error),
80}
81
82impl ToolError {
83 pub fn network<E>(source: E) -> Self
86 where
87 E: std::error::Error + Send + Sync + 'static,
88 {
89 Self::Network {
90 message: source.to_string(),
91 source: Some(Box::new(source)),
92 }
93 }
94
95 pub fn network_msg(message: impl Into<String>) -> Self {
98 Self::Network {
99 message: message.into(),
100 source: None,
101 }
102 }
103
104 pub fn config<E>(source: E) -> Self
107 where
108 E: std::error::Error + Send + Sync + 'static,
109 {
110 Self::Config {
111 message: source.to_string(),
112 source: Some(Box::new(source)),
113 }
114 }
115
116 pub fn config_msg(message: impl Into<String>) -> Self {
118 Self::Config {
119 message: message.into(),
120 source: None,
121 }
122 }
123}
124
125impl From<ToolError> for Error {
126 fn from(err: ToolError) -> Self {
127 match err {
128 ToolError::Config { .. } => Self::config(err.to_string()),
129 ToolError::BodyTooLarge { .. } => Self::provider_http_from(413, err),
130 ToolError::Network { .. } => Self::provider_network_from(err),
131 ToolError::InvalidInput(_)
133 | ToolError::HostBlocked { .. }
134 | ToolError::UnsupportedScheme { .. }
135 | ToolError::MethodBlocked { .. }
136 | ToolError::Calculator(_)
137 | ToolError::Serde(_) => Self::invalid_request(err.to_string()),
138 }
139 }
140}