vtcode_core/open_responses/
error.rs1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, thiserror::Error)]
13#[error("{error_type}: {message}")]
14pub struct OpenResponseError {
15 #[serde(rename = "type")]
17 pub error_type: OpenResponseErrorType,
18
19 #[serde(skip_serializing_if = "Option::is_none")]
21 pub code: Option<OpenResponseErrorCode>,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub param: Option<String>,
26
27 pub message: String,
29}
30
31impl OpenResponseError {
32 pub fn new(error_type: OpenResponseErrorType, message: impl Into<String>) -> Self {
34 Self {
35 error_type,
36 code: None,
37 param: None,
38 message: message.into(),
39 }
40 }
41
42 pub fn server_error(message: impl Into<String>) -> Self {
44 Self::new(OpenResponseErrorType::ServerError, message)
45 }
46
47 pub fn invalid_request(message: impl Into<String>) -> Self {
49 Self::new(OpenResponseErrorType::InvalidRequest, message)
50 }
51
52 pub fn invalid_param(param: impl Into<String>, message: impl Into<String>) -> Self {
54 Self {
55 error_type: OpenResponseErrorType::InvalidRequest,
56 code: None,
57 param: Some(param.into()),
58 message: message.into(),
59 }
60 }
61
62 pub fn model_error(message: impl Into<String>) -> Self {
64 Self::new(OpenResponseErrorType::ModelError, message)
65 }
66
67 pub fn not_found(message: impl Into<String>) -> Self {
69 Self::new(OpenResponseErrorType::NotFound, message)
70 }
71
72 pub fn rate_limit(message: impl Into<String>) -> Self {
74 Self::new(OpenResponseErrorType::TooManyRequests, message)
75 }
76
77 pub fn with_code(mut self, code: OpenResponseErrorCode) -> Self {
79 self.code = Some(code);
80 self
81 }
82
83 pub fn with_param(mut self, param: impl Into<String>) -> Self {
85 self.param = Some(param.into());
86 self
87 }
88}
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
92#[serde(rename_all = "snake_case")]
93pub enum OpenResponseErrorType {
94 ServerError,
96
97 InvalidRequest,
99
100 NotFound,
102
103 ModelError,
105
106 TooManyRequests,
108
109 AuthenticationError,
111
112 PermissionDenied,
114}
115
116impl std::fmt::Display for OpenResponseErrorType {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 match self {
119 Self::ServerError => write!(f, "server_error"),
120 Self::InvalidRequest => write!(f, "invalid_request"),
121 Self::NotFound => write!(f, "not_found"),
122 Self::ModelError => write!(f, "model_error"),
123 Self::TooManyRequests => write!(f, "too_many_requests"),
124 Self::AuthenticationError => write!(f, "authentication_error"),
125 Self::PermissionDenied => write!(f, "permission_denied"),
126 }
127 }
128}
129
130#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
132#[serde(rename_all = "snake_case")]
133pub enum OpenResponseErrorCode {
134 InvalidApiKey,
136
137 InsufficientQuota,
139
140 ContextLengthExceeded,
142
143 InvalidModel,
145
146 ContentFilter,
148
149 ToolExecutionFailed,
151
152 Timeout,
154
155 RateLimitExceeded,
157
158 #[serde(untagged)]
160 Custom(String),
161}
162
163impl std::fmt::Display for OpenResponseErrorCode {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 match self {
166 Self::InvalidApiKey => write!(f, "invalid_api_key"),
167 Self::InsufficientQuota => write!(f, "insufficient_quota"),
168 Self::ContextLengthExceeded => write!(f, "context_length_exceeded"),
169 Self::InvalidModel => write!(f, "invalid_model"),
170 Self::ContentFilter => write!(f, "content_filter"),
171 Self::ToolExecutionFailed => write!(f, "tool_execution_failed"),
172 Self::Timeout => write!(f, "timeout"),
173 Self::RateLimitExceeded => write!(f, "rate_limit_exceeded"),
174 Self::Custom(code) => write!(f, "{}", code),
175 }
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182
183 #[test]
184 fn test_error_creation() {
185 let err = OpenResponseError::invalid_param("model", "Invalid model ID");
186 assert_eq!(err.error_type, OpenResponseErrorType::InvalidRequest);
187 assert_eq!(err.param, Some("model".to_string()));
188 assert_eq!(err.message, "Invalid model ID");
189 }
190
191 #[test]
192 fn test_error_serialization() {
193 let err = OpenResponseError::server_error("Internal error")
194 .with_code(OpenResponseErrorCode::Timeout);
195 let json = serde_json::to_string(&err).unwrap();
196 assert!(json.contains("\"type\":\"server_error\""));
197 assert!(json.contains("\"code\":\"timeout\""));
198 }
199}