Skip to main content

llmg_core/
error.rs

1//! Error types for LLMG
2//!
3//! These types are compatible with the OpenAI API error format.
4
5use serde::{Deserialize, Serialize};
6
7/// OpenAI-compatible error response
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct ErrorResponse {
10    /// The error object
11    pub error: ErrorDetail,
12}
13
14/// Detailed error information
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct ErrorDetail {
17    /// Error message
18    pub message: String,
19    /// Error type
20    pub r#type: String,
21    /// Parameter that caused the error (if applicable)
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub param: Option<String>,
24    /// Error code
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub code: Option<String>,
27}
28
29impl ErrorResponse {
30    /// Create a new error response
31    pub fn new(message: impl Into<String>, error_type: impl Into<String>) -> Self {
32        Self {
33            error: ErrorDetail {
34                message: message.into(),
35                r#type: error_type.into(),
36                param: None,
37                code: None,
38            },
39        }
40    }
41
42    /// Create an invalid request error
43    pub fn invalid_request(message: impl Into<String>) -> Self {
44        Self::new(message, "invalid_request_error")
45    }
46
47    /// Create an authentication error
48    pub fn authentication_error() -> Self {
49        Self::new("Invalid authentication", "authentication_error")
50    }
51
52    /// Create a rate limit error
53    pub fn rate_limit_error() -> Self {
54        Self::new("Rate limit exceeded", "rate_limit_error")
55    }
56
57    /// Create a server error
58    pub fn server_error(message: impl Into<String>) -> Self {
59        Self::new(message, "server_error")
60    }
61}
62
63/// Normalize provider errors to OpenAI format
64pub fn normalize_error(status: u16, message: impl Into<String>) -> ErrorResponse {
65    let message = message.into();
66    match status {
67        400 => ErrorResponse::invalid_request(message),
68        401 => ErrorResponse::authentication_error(),
69        429 => ErrorResponse::rate_limit_error(),
70        _ => ErrorResponse::server_error(message),
71    }
72}
73
74impl std::fmt::Display for ErrorResponse {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        write!(f, "{}: {}", self.error.r#type, self.error.message)
77    }
78}
79
80impl std::error::Error for ErrorResponse {}