vtcode_core/tools/registry/
error.rs1use anyhow::Error;
2use serde::{Deserialize, Serialize};
3use serde_json::{Value, json};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct ToolExecutionError {
7 pub tool_name: String,
8 pub error_type: ToolErrorType,
9 pub message: String,
10 pub is_recoverable: bool,
11 pub recovery_suggestions: Vec<String>,
12 pub original_error: Option<String>,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub enum ToolErrorType {
17 InvalidParameters,
18 ToolNotFound,
19 PermissionDenied,
20 ResourceNotFound,
21 NetworkError,
22 Timeout,
23 ExecutionError,
24 PolicyViolation,
25}
26
27impl ToolExecutionError {
28 pub fn new(tool_name: String, error_type: ToolErrorType, message: String) -> Self {
29 let (is_recoverable, recovery_suggestions) = generate_recovery_info(&error_type);
30
31 Self {
32 tool_name,
33 error_type,
34 message,
35 is_recoverable,
36 recovery_suggestions,
37 original_error: None,
38 }
39 }
40
41 pub fn with_original_error(
42 tool_name: String,
43 error_type: ToolErrorType,
44 message: String,
45 original_error: String,
46 ) -> Self {
47 let mut error = Self::new(tool_name, error_type, message);
48 error.original_error = Some(original_error);
49 error
50 }
51
52 pub fn to_json_value(&self) -> Value {
53 json!({
54 "error": {
55 "tool_name": self.tool_name,
56 "error_type": format!("{:?}", self.error_type),
57 "message": self.message,
58 "is_recoverable": self.is_recoverable,
59 "recovery_suggestions": self.recovery_suggestions,
60 "original_error": self.original_error,
61 }
62 })
63 }
64}
65
66pub fn classify_error(error: &Error) -> ToolErrorType {
67 let error_msg = error.to_string().to_lowercase();
68
69 if error_msg.contains("permission") || error_msg.contains("access denied") {
70 ToolErrorType::PermissionDenied
71 } else if error_msg.contains("not found") || error_msg.contains("no such file") {
72 ToolErrorType::ResourceNotFound
73 } else if error_msg.contains("timeout") || error_msg.contains("timed out") {
74 ToolErrorType::Timeout
75 } else if error_msg.contains("network") || error_msg.contains("connection") {
76 ToolErrorType::NetworkError
77 } else if error_msg.contains("invalid") || error_msg.contains("malformed") {
78 ToolErrorType::InvalidParameters
79 } else if error_msg.contains("policy") || error_msg.contains("denied") {
80 ToolErrorType::PolicyViolation
81 } else {
82 ToolErrorType::ExecutionError
83 }
84}
85
86fn generate_recovery_info(error_type: &ToolErrorType) -> (bool, Vec<String>) {
87 match error_type {
88 ToolErrorType::InvalidParameters => (
89 true,
90 vec![
91 "Check parameter names and types against the tool schema".to_string(),
92 "Ensure required parameters are provided".to_string(),
93 "Verify parameter values are within acceptable ranges".to_string(),
94 ],
95 ),
96 ToolErrorType::ToolNotFound => (
97 false,
98 vec![
99 "Verify the tool name is spelled correctly".to_string(),
100 "Check if the tool is available in the current context".to_string(),
101 "Contact administrator if tool should be available".to_string(),
102 ],
103 ),
104 ToolErrorType::PermissionDenied => (
105 true,
106 vec![
107 "Check file permissions and access rights".to_string(),
108 "Ensure workspace boundaries are respected".to_string(),
109 "Try running with appropriate permissions".to_string(),
110 ],
111 ),
112 ToolErrorType::ResourceNotFound => (
113 true,
114 vec![
115 "Verify file paths and resource locations".to_string(),
116 "Check if files exist and are accessible".to_string(),
117 "Use list_dir to explore available resources".to_string(),
118 ],
119 ),
120 ToolErrorType::NetworkError => (
121 true,
122 vec![
123 "Check network connectivity".to_string(),
124 "Retry the operation after a brief delay".to_string(),
125 "Verify external service availability".to_string(),
126 ],
127 ),
128 ToolErrorType::Timeout => (
129 true,
130 vec![
131 "Increase timeout values if appropriate".to_string(),
132 "Break large operations into smaller chunks".to_string(),
133 "Check system resources and performance".to_string(),
134 ],
135 ),
136 ToolErrorType::ExecutionError => (
137 false,
138 vec![
139 "Review error details for specific issues".to_string(),
140 "Check tool documentation for known limitations".to_string(),
141 "Report the issue if it appears to be a bug".to_string(),
142 ],
143 ),
144 ToolErrorType::PolicyViolation => (
145 false,
146 vec![
147 "Review workspace policies and restrictions".to_string(),
148 "Contact administrator for policy changes".to_string(),
149 "Use alternative tools that comply with policies".to_string(),
150 ],
151 ),
152 }
153}