1use eventsource_stream::EventStreamError;
2use thiserror::Error;
3
4#[derive(Error, Debug, Clone, PartialEq, Eq)]
5pub enum SseParseError {
6 #[error("UTF-8 error: {details}")]
7 Utf8 { details: String },
8 #[error("Parse error: {details}")]
9 Parser { details: String },
10 #[error("Transport error: {details}")]
11 Transport { details: String },
12}
13
14impl<E> From<EventStreamError<E>> for SseParseError
15where
16 E: std::error::Error,
17{
18 fn from(err: EventStreamError<E>) -> Self {
19 match err {
20 EventStreamError::Utf8(err) => Self::Utf8 {
21 details: err.to_string(),
22 },
23 EventStreamError::Parser(err) => Self::Parser {
24 details: err.to_string(),
25 },
26 EventStreamError::Transport(err) => Self::Transport {
27 details: err.to_string(),
28 },
29 }
30 }
31}
32
33#[derive(Error, Debug, Clone, PartialEq, Eq)]
34pub enum StreamError {
35 #[error("Request cancelled")]
36 Cancelled,
37
38 #[error("SSE parse error: {0}")]
39 SseParse(SseParseError),
40
41 #[error("{provider} error ({error_type}): {message}")]
42 Provider {
43 provider: String,
44 error_type: String,
45 message: String,
46 },
47}
48
49#[derive(Error, Debug)]
50pub enum ApiError {
51 #[error("Network error: {0}")]
52 Network(#[from] reqwest::Error),
53
54 #[error("Authentication failed: {details}")]
55 AuthenticationFailed { provider: String, details: String },
56
57 #[error("Auth error: {0}")]
58 AuthError(String),
59
60 #[error("Rate limited by {provider}: {details}")]
61 RateLimited { provider: String, details: String },
62
63 #[error("Invalid request to {provider}: {details}")]
64 InvalidRequest { provider: String, details: String },
65
66 #[error("{provider} server error (Status: {status_code}): {details}")]
67 ServerError {
68 provider: String,
69 status_code: u16,
70 details: String,
71 },
72
73 #[error("Request timed out for {provider}")]
74 Timeout { provider: String },
75
76 #[error("Request cancelled for {provider}")]
77 Cancelled { provider: String },
78
79 #[error("Failed to parse response from {provider}: {details}")]
80 ResponseParsingError { provider: String, details: String },
81
82 #[error("API returned no choices/candidates for {provider}")]
83 NoChoices { provider: String },
84
85 #[error("Request blocked by {provider}: {details}")]
86 RequestBlocked { provider: String, details: String },
87
88 #[error("Unknown API error from {provider}: {details}")]
89 Unknown { provider: String, details: String },
90
91 #[error("Configuration error: {0}")]
92 Configuration(String),
93
94 #[error("Stream error from {provider}: {details}")]
95 StreamError { provider: String, details: String },
96}
97
98impl From<crate::error::Error> for ApiError {
99 fn from(err: crate::error::Error) -> Self {
100 match err {
101 crate::error::Error::Api(api_err) => api_err,
102 crate::error::Error::Configuration(msg) => ApiError::Configuration(msg),
103 other => ApiError::Unknown {
104 provider: "internal".to_string(),
105 details: format!("Unexpected internal error: {other}"),
106 },
107 }
108 }
109}