Skip to main content

rust_tg_bot_raw/
error.rs

1use std::time::Duration;
2
3/// Base error type for all Telegram Bot API errors.
4#[derive(Debug, thiserror::Error)]
5#[non_exhaustive]
6pub enum TelegramError {
7    /// The bot doesn't have enough rights to perform the requested action.
8    #[error("{0}")]
9    Forbidden(String),
10
11    /// The provided token is invalid.
12    #[error("{0}")]
13    InvalidToken(String),
14
15    /// The requested API endpoint was not found.
16    #[error("{0}")]
17    EndPointNotFound(String),
18
19    /// A network-level error occurred.
20    #[error("{0}")]
21    Network(String),
22
23    /// Telegram returned a 400 Bad Request response.
24    #[error("{0}")]
25    BadRequest(String),
26
27    /// The request timed out.
28    #[error("{0}")]
29    TimedOut(String),
30
31    /// The chat was migrated to a supergroup with a new ID.
32    #[error("Group migrated to supergroup. New chat id: {new_chat_id}")]
33    ChatMigrated {
34        /// The new chat ID of the supergroup.
35        new_chat_id: i64,
36    },
37
38    /// Flood control -- must wait before retrying.
39    #[error("Flood control exceeded. Retry in {retry_after:?}")]
40    RetryAfter {
41        /// Duration to wait before retrying the request.
42        retry_after: Duration,
43    },
44
45    /// A long-poll or webhook conflicts with another one.
46    #[error("{0}")]
47    Conflict(String),
48
49    /// Passport decryption failed.
50    #[error("PassportDecryptionError: {0}")]
51    PassportDecryption(String),
52
53    /// HTTP-level error from reqwest.
54    #[error("HTTP error: {0}")]
55    Http(#[from] reqwest::Error),
56
57    /// JSON serialization/deserialization error.
58    #[error("JSON error: {0}")]
59    Json(#[from] serde_json::Error),
60
61    /// I/O error.
62    #[error("IO error: {0}")]
63    Io(#[from] std::io::Error),
64}
65
66impl TelegramError {
67    /// Cleans the error prefix from API error messages, matching python-telegram-bot behavior.
68    pub fn from_api_message(message: &str) -> String {
69        let msg = message
70            .strip_prefix("Error: ")
71            .or_else(|| message.strip_prefix("[Error]: "))
72            .or_else(|| message.strip_prefix("Bad Request: "));
73
74        match msg {
75            Some(stripped) => {
76                let mut chars = stripped.chars();
77                match chars.next() {
78                    Some(c) => c.to_uppercase().to_string() + chars.as_str(),
79                    None => String::new(),
80                }
81            }
82            None => message.to_string(),
83        }
84    }
85}
86
87/// A type alias for `Result<T, TelegramError>`.
88pub type Result<T> = std::result::Result<T, TelegramError>;