universal_tool_core/
error.rs1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4use thiserror::Error;
5
6#[derive(Debug, Error, Serialize, Deserialize, JsonSchema)]
8pub struct ToolError {
9 pub code: ErrorCode,
11 pub message: String,
13 #[serde(skip_serializing_if = "Option::is_none")]
15 pub details: Option<HashMap<String, serde_json::Value>>,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
20pub enum ErrorCode {
21 BadRequest,
22 InvalidArgument,
23 NotFound,
24 PermissionDenied,
25 Internal,
26 Timeout,
27 Conflict,
28 NetworkError,
29 ExternalServiceError,
30 ExecutionFailed,
31 SerializationError,
32 IoError,
33}
34
35impl std::fmt::Display for ToolError {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 write!(f, "[{:?}] {}", self.code, self.message)
39 }
40}
41
42impl ToolError {
44 pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
46 Self {
47 code,
48 message: message.into(),
49 details: None,
50 }
51 }
52
53 pub fn with_details(mut self, details: HashMap<String, serde_json::Value>) -> Self {
55 self.details = Some(details);
56 self
57 }
58
59 pub fn with_detail(mut self, key: &str, value: impl Into<serde_json::Value>) -> Self {
61 let mut details = self.details.unwrap_or_default();
62 details.insert(key.to_string(), value.into());
63 self.details = Some(details);
64 self
65 }
66
67 pub fn internal(message: impl Into<String>) -> Self {
69 Self::new(ErrorCode::Internal, message)
70 }
71
72 pub fn not_found(message: impl Into<String>) -> Self {
73 Self::new(ErrorCode::NotFound, message)
74 }
75
76 pub fn invalid_input(message: impl Into<String>) -> Self {
77 Self::new(ErrorCode::InvalidArgument, message)
78 }
79
80 pub fn conflict(message: impl Into<String>) -> Self {
81 Self::new(ErrorCode::Conflict, message)
82 }
83}
84
85impl From<std::io::Error> for ToolError {
87 fn from(err: std::io::Error) -> Self {
88 Self::new(ErrorCode::ExecutionFailed, err.to_string())
89 }
90}
91
92impl From<serde_json::Error> for ToolError {
93 fn from(err: serde_json::Error) -> Self {
94 Self::new(ErrorCode::InvalidArgument, err.to_string())
95 }
96}
97
98impl From<String> for ToolError {
99 fn from(err: String) -> Self {
100 Self::new(ErrorCode::ExecutionFailed, err)
101 }
102}
103
104impl From<&str> for ToolError {
105 fn from(err: &str) -> Self {
106 Self::new(ErrorCode::ExecutionFailed, err)
107 }
108}