1use miyabi_types::error::{ErrorCode, UnifiedError};
4use std::any::Any;
5use thiserror::Error;
6
7#[derive(Error, Debug)]
9pub enum TelegramError {
10 #[error("HTTP request failed: {0}")]
12 HttpError(#[from] reqwest::Error),
13
14 #[error("JSON error: {0}")]
16 JsonError(#[from] serde_json::Error),
17
18 #[error("Telegram API error: {0}")]
20 ApiError(String),
21
22 #[error("Invalid bot token")]
24 InvalidToken,
25
26 #[error("Missing environment variable: {0}")]
28 MissingEnvVar(String),
29
30 #[error("Other error: {0}")]
32 Other(String),
33}
34
35pub type Result<T> = std::result::Result<T, TelegramError>;
37
38impl UnifiedError for TelegramError {
43 fn code(&self) -> ErrorCode {
44 match self {
45 Self::HttpError(_) => ErrorCode::HTTP_ERROR,
46 Self::JsonError(_) => ErrorCode::PARSE_ERROR,
47 Self::ApiError(_) => ErrorCode::HTTP_ERROR,
48 Self::InvalidToken => ErrorCode::AUTH_ERROR,
49 Self::MissingEnvVar(_) => ErrorCode::MISSING_CONFIG,
50 Self::Other(_) => ErrorCode::INTERNAL_ERROR,
51 }
52 }
53
54 fn user_message(&self) -> String {
55 match self {
56 Self::ApiError(msg) => format!(
57 "Telegram API returned an error: {}. Please check your bot configuration and try again.",
58 msg
59 ),
60 Self::InvalidToken => {
61 "Invalid Telegram bot token. Please verify your bot token in the configuration.".to_string()
62 }
63 Self::MissingEnvVar(var) => format!(
64 "Missing environment variable: {}. Please set this variable in your .env file or environment.",
65 var
66 ),
67 Self::Other(msg) => format!(
68 "Telegram bot error: {}. Please check logs for more details.",
69 msg
70 ),
71 _ => self.to_string(),
73 }
74 }
75
76 fn context(&self) -> Option<&dyn Any> {
77 match self {
78 Self::ApiError(msg) => Some(msg as &dyn Any),
79 Self::MissingEnvVar(var) => Some(var as &dyn Any),
80 Self::Other(msg) => Some(msg as &dyn Any),
81 _ => None,
82 }
83 }
84}
85
86#[cfg(test)]
87mod unified_error_tests {
88 use super::*;
89
90 #[test]
91 fn test_telegram_error_codes() {
92 let error = TelegramError::ApiError("rate limit".to_string());
93 assert_eq!(error.code(), ErrorCode::HTTP_ERROR);
94
95 let error = TelegramError::InvalidToken;
96 assert_eq!(error.code(), ErrorCode::AUTH_ERROR);
97
98 let error = TelegramError::MissingEnvVar("TELEGRAM_BOT_TOKEN".to_string());
99 assert_eq!(error.code(), ErrorCode::MISSING_CONFIG);
100
101 let error = TelegramError::Other("unknown".to_string());
102 assert_eq!(error.code(), ErrorCode::INTERNAL_ERROR);
103 }
104
105 #[test]
106 fn test_user_messages() {
107 let error = TelegramError::ApiError("Bad Request: message too long".to_string());
108 let msg = error.user_message();
109 assert!(msg.contains("Telegram API"));
110 assert!(msg.contains("message too long"));
111
112 let error = TelegramError::InvalidToken;
113 let msg = error.user_message();
114 assert!(msg.contains("Invalid"));
115 assert!(msg.contains("bot token"));
116
117 let error = TelegramError::MissingEnvVar("TELEGRAM_CHAT_ID".to_string());
118 let msg = error.user_message();
119 assert!(msg.contains("Missing environment variable"));
120 assert!(msg.contains("TELEGRAM_CHAT_ID"));
121 }
122
123 #[test]
124 fn test_context_extraction() {
125 let error = TelegramError::ApiError("error".to_string());
126 assert!(error.context().is_some());
127
128 let error = TelegramError::MissingEnvVar("TOKEN".to_string());
129 assert!(error.context().is_some());
130
131 let error = TelegramError::InvalidToken;
132 assert!(error.context().is_none());
133
134 }
138}