use teloxide::{DownloadError, RequestError};
pub(super) fn request_error_class(error: &RequestError) -> &'static str {
match error {
RequestError::Api(_) => "telegram_api",
RequestError::MigrateToChatId(_) => "telegram_migrate",
RequestError::RetryAfter(_) => "telegram_rate_limit",
RequestError::Network(network) if network.is_timeout() => "telegram_network_timeout",
RequestError::Network(network) if network.is_connect() => "telegram_network_connect",
RequestError::Network(_) => "telegram_network",
RequestError::InvalidJson { .. } => "telegram_invalid_json",
RequestError::Io(error) => io_error_class(error.kind()),
}
}
fn download_error_class(error: &DownloadError) -> &'static str {
match error {
DownloadError::Network(network) if network.is_timeout() => {
"telegram_download_network_timeout"
}
DownloadError::Network(network) if network.is_connect() => {
"telegram_download_network_connect"
}
DownloadError::Network(_) => "telegram_download_network",
DownloadError::Io(error) => io_error_class(error.kind()),
}
}
fn io_error_class(kind: std::io::ErrorKind) -> &'static str {
match kind {
std::io::ErrorKind::TimedOut => "io_timeout",
std::io::ErrorKind::ConnectionRefused => "io_connection_refused",
std::io::ErrorKind::ConnectionReset => "io_connection_reset",
std::io::ErrorKind::ConnectionAborted => "io_connection_aborted",
std::io::ErrorKind::NotConnected => "io_not_connected",
std::io::ErrorKind::BrokenPipe => "io_broken_pipe",
std::io::ErrorKind::UnexpectedEof => "io_unexpected_eof",
std::io::ErrorKind::PermissionDenied => "io_permission_denied",
std::io::ErrorKind::NotFound => "io_not_found",
_ => "io_other",
}
}
pub(super) fn anyhow_error_class(error: &anyhow::Error) -> &'static str {
for cause in error.chain() {
if let Some(request_error) = cause.downcast_ref::<RequestError>() {
return request_error_class(request_error);
}
if let Some(download_error) = cause.downcast_ref::<DownloadError>() {
return download_error_class(download_error);
}
if let Some(sqlite_error) = cause.downcast_ref::<rusqlite::Error>() {
return match sqlite_error {
rusqlite::Error::SqliteFailure(_, _) => "sqlite_failure",
rusqlite::Error::QueryReturnedNoRows => "sqlite_not_found",
rusqlite::Error::InvalidQuery => "sqlite_invalid_query",
_ => "sqlite_other",
};
}
if let Some(io_error) = cause.downcast_ref::<std::io::Error>() {
return io_error_class(io_error.kind());
}
}
"local_processing"
}