vtcode_core/tools/
error_helpers.rs1use anyhow::{Context, Result};
4use std::fmt::Display;
5use std::path::Path;
6
7pub fn with_file_context<T, E>(
10 result: std::result::Result<T, E>,
11 operation: impl Display,
12 path: &Path,
13) -> Result<T>
14where
15 E: std::error::Error + Send + Sync + 'static,
16{
17 result.with_context(|| format!("Failed to {operation} '{}'", path.display()))
18}
19
20pub fn with_path_context<T, E>(
22 result: std::result::Result<T, E>,
23 operation: impl Display,
24 path: impl Display,
25) -> Result<T>
26where
27 E: std::error::Error + Send + Sync + 'static,
28{
29 result.with_context(|| format!("Failed to {operation} {path}"))
30}
31
32#[cold]
34pub fn require_string_field(
35 args: &serde_json::Value,
36 field: &str,
37 tool_name: &str,
38) -> Result<String> {
39 args.get(field)
40 .and_then(|v| v.as_str())
41 .map(|s| s.to_string())
42 .ok_or_else(|| anyhow::anyhow!("{field} is required for {tool_name}"))
43}
44
45pub fn optional_string_field(args: &serde_json::Value, field: &str) -> Option<String> {
47 args.get(field)
48 .and_then(|v| v.as_str())
49 .map(|s| s.to_string())
50}
51
52#[cold]
54pub fn require_int_field(args: &serde_json::Value, field: &str, tool_name: &str) -> Result<i64> {
55 args.get(field)
56 .and_then(|v| v.as_i64())
57 .ok_or_else(|| anyhow::anyhow!("{field} is required for {tool_name}"))
58}
59
60#[cold]
63pub fn require_field<T>(value: Option<T>, field: &str, tool_name: &str) -> Result<T> {
64 value.ok_or_else(|| anyhow::anyhow!("{field} is required for {tool_name}"))
65}
66
67pub fn deserialize_tool_args<T: serde::de::DeserializeOwned>(
72 args: &serde_json::Value,
73 tool_name: &str,
74) -> Result<T> {
75 serde_json::from_value(args.clone())
76 .map_err(|e| anyhow::anyhow!("Error: Invalid '{}' arguments: {}", tool_name, e))
77}