diff --git a/Cargo.lock b/Cargo.lock index 38f01d0..d5c85a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -368,6 +368,7 @@ dependencies = [ name = "book_bot" version = "0.1.0" dependencies = [ + "anyhow", "axum", "axum-prometheus", "base64", diff --git a/Cargo.toml b/Cargo.toml index 747128b..169f4bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,3 +54,4 @@ smartstring = { version = "1.0.1", features = ["serde"] } moka = { version = "0.12.10", features = ["future"] } sentry = { version = "0.40.0", features = ["debug-images"] } +anyhow = "1.0.98" diff --git a/src/bots/approved_bot/mod.rs b/src/bots/approved_bot/mod.rs index d43ac19..faf15a0 100644 --- a/src/bots/approved_bot/mod.rs +++ b/src/bots/approved_bot/mod.rs @@ -24,8 +24,8 @@ use self::{ }; use super::{ - bots_manager::get_manager_handler, ignore_channel_messages, ignore_chat_member_update, - ignore_user_edited_message, ingore_chat_join_request, BotCommands, BotHandler, + bots_manager::get_manager_handler, ignore_channel_messages, ignore_chat_join_request, + ignore_chat_member_update, ignore_user_edited_message, BotCommands, BotHandler, }; async fn _update_activity(me: teloxide::types::Me, user: teloxide::types::User) -> Option<()> { @@ -87,7 +87,7 @@ pub fn get_approved_handler() -> (BotHandler, BotCommands) { .branch(ignore_channel_messages()) .branch(ignore_chat_member_update()) .branch(ignore_user_edited_message()) - .branch(ingore_chat_join_request()) + .branch(ignore_chat_join_request()) .branch(update_user_activity_handler()) .branch(get_help_handler()) .branch(get_settings_handler()) diff --git a/src/bots/approved_bot/modules/annotations/mod.rs b/src/bots/approved_bot/modules/annotations/mod.rs index fb29ed4..2d77c6c 100644 --- a/src/bots/approved_bot/modules/annotations/mod.rs +++ b/src/bots/approved_bot/modules/annotations/mod.rs @@ -46,7 +46,7 @@ pub async fn send_annotation_handler( ) -> BotHandlerInternal where T: AnnotationFormat, - Fut: std::future::Future>>, + Fut: std::future::Future>, { let id = match command { AnnotationCommand::Book { id } => id, @@ -63,7 +63,7 @@ where .await { Ok(_) => Ok(()), - Err(err) => Err(Box::new(err)), + Err(err) => Err(err.into()), }; }; @@ -87,10 +87,11 @@ where }; if !annotation.is_normal_text() { - return Err(Box::new(AnnotationFormatError { + return Err(AnnotationFormatError { _command: command, _text: annotation.get_text().to_string(), - })); + } + .into()); } let annotation_text = annotation.get_text(); @@ -120,7 +121,7 @@ pub async fn annotation_pagination_handler( ) -> BotHandlerInternal where T: AnnotationFormat, - Fut: std::future::Future>>, + Fut: std::future::Future>, { let (id, page) = match callback_data { AnnotationCallbackData::Book { id, page } => (id, page), diff --git a/src/bots/approved_bot/modules/book/mod.rs b/src/bots/approved_bot/modules/book/mod.rs index 00ee569..35b75fc 100644 --- a/src/bots/approved_bot/modules/book/mod.rs +++ b/src/bots/approved_bot/modules/book/mod.rs @@ -39,7 +39,7 @@ async fn send_book_handler( where T: Format + Clone + Debug, P: FormatTitle + Clone + Debug, - Fut: std::future::Future, Box>>, + Fut: std::future::Future>>, { let id = match command { BookCommand::Author { id } => id, @@ -59,7 +59,7 @@ where .await { Ok(_) => Ok(()), - Err(err) => Err(Box::new(err)), + Err(err) => Err(err.into()), } } }; @@ -110,7 +110,7 @@ async fn send_pagination_book_handler( where T: Format + Clone + Debug, P: FormatTitle + Clone + Debug, - Fut: std::future::Future, Box>>, + Fut: std::future::Future>>, { let (id, page) = match callback_data { BookCallbackData::Author { id, page } => (id, page), diff --git a/src/bots/approved_bot/modules/download/mod.rs b/src/bots/approved_bot/modules/download/mod.rs index 922fb28..2717c42 100644 --- a/src/bots/approved_bot/modules/download/mod.rs +++ b/src/bots/approved_bot/modules/download/mod.rs @@ -77,7 +77,7 @@ async fn _send_cached( .await { Ok(_) => Ok(()), - Err(err) => Err(Box::new(err)), + Err(err) => Err(err.into()), } } @@ -145,7 +145,7 @@ async fn _send_downloaded_file( Ok(_) => (), Err(err) => { log::error!("Download error: {:?} | {:?}", filename, err); - return Err(Box::new(err)); + return Err(err.into()); } } @@ -163,27 +163,22 @@ async fn send_with_download_from_channel( download_data: DownloadQueryData, need_delete_message: bool, ) -> BotHandlerInternal { - match download_file(&download_data).await { - Ok(v) => { - let download_file = match v { - Some(v) => v, - None => { - return Ok(()); - } - }; - - _send_downloaded_file(&message, bot.clone(), download_file).await?; - - if need_delete_message { - if let MaybeInaccessibleMessage::Regular(message) = message { - bot.delete_message(message.chat.id, message.id).await?; - }; - } - - Ok(()) + let downloaded_file = match download_file(&download_data).await? { + Some(v) => v, + None => { + return Ok(()); } - Err(err) => Err(err), + }; + + _send_downloaded_file(&message, bot.clone(), downloaded_file).await?; + + if need_delete_message { + if let MaybeInaccessibleMessage::Regular(message) = message { + bot.delete_message(message.chat.id, message.id).await?; + }; } + + Ok(()) } async fn download_handler( diff --git a/src/bots/approved_bot/modules/help/mod.rs b/src/bots/approved_bot/modules/help/mod.rs index 104440c..1d409ca 100644 --- a/src/bots/approved_bot/modules/help/mod.rs +++ b/src/bots/approved_bot/modules/help/mod.rs @@ -38,7 +38,7 @@ pub async fn help_handler(message: Message, bot: CacheMe>) -> BotH .await { Ok(_) => Ok(()), - Err(err) => Err(Box::new(err)), + Err(err) => Err(err.into()), } } diff --git a/src/bots/approved_bot/modules/random/mod.rs b/src/bots/approved_bot/modules/random/mod.rs index 847e8fb..722a31b 100644 --- a/src/bots/approved_bot/modules/random/mod.rs +++ b/src/bots/approved_bot/modules/random/mod.rs @@ -70,7 +70,7 @@ async fn random_handler( async fn get_random_item_handler_internal( cq: CallbackQuery, bot: CacheMe>, - item: Result>, + item: anyhow::Result, ) -> BotHandlerInternal where T: Format, @@ -118,7 +118,7 @@ async fn get_random_item_handler( ) -> BotHandlerInternal where T: Format, - Fut: std::future::Future>>, + Fut: std::future::Future>, { let allowed_langs = get_user_or_default_lang_codes(cq.from.id).await; diff --git a/src/bots/approved_bot/modules/search/mod.rs b/src/bots/approved_bot/modules/search/mod.rs index 734b5a0..cd62e76 100644 --- a/src/bots/approved_bot/modules/search/mod.rs +++ b/src/bots/approved_bot/modules/search/mod.rs @@ -40,7 +40,7 @@ async fn generic_search_pagination_handler( where T: Format + Clone + Debug, P: FormatTitle + Clone + Debug, - Fut: std::future::Future, Box>>, + Fut: std::future::Future>>, { let chat_id = cq.chat_id(); let user_id = cq.from.id; @@ -106,11 +106,11 @@ where }; } - let formated_page = items_page.format(page, 4096); + let formatted_page = items_page.format(page, 4096); let keyboard = generic_get_pagination_keyboard(page, items_page.pages, search_data, true); - bot.edit_message_text(chat_id, message_id, formated_page) + bot.edit_message_text(chat_id, message_id, formatted_page) .reply_markup(keyboard) .send() .await?; diff --git a/src/bots/approved_bot/modules/update_history/mod.rs b/src/bots/approved_bot/modules/update_history/mod.rs index 609d5a7..8c2379c 100644 --- a/src/bots/approved_bot/modules/update_history/mod.rs +++ b/src/bots/approved_bot/modules/update_history/mod.rs @@ -69,7 +69,7 @@ async fn update_log_command(message: Message, bot: CacheMe>) -> Bo .await { Ok(_) => Ok(()), - Err(err) => Err(Box::new(err)), + Err(err) => Err(err.into()), } } diff --git a/src/bots/approved_bot/services/batch_downloader.rs b/src/bots/approved_bot/services/batch_downloader.rs index 9394ca7..1bd3ab5 100644 --- a/src/bots/approved_bot/services/batch_downloader.rs +++ b/src/bots/approved_bot/services/batch_downloader.rs @@ -43,9 +43,7 @@ pub struct Task { pub content_size: Option, } -pub async fn create_task( - data: CreateTaskData, -) -> Result> { +pub async fn create_task(data: CreateTaskData) -> anyhow::Result { Ok(CLIENT .post(format!("{}/api/", &config::CONFIG.batch_downloader_url)) .body(serde_json::to_string(&data).unwrap()) @@ -58,7 +56,7 @@ pub async fn create_task( .await?) } -pub async fn get_task(task_id: String) -> Result> { +pub async fn get_task(task_id: String) -> anyhow::Result { Ok(CLIENT .get(format!( "{}/api/check_archive/{task_id}", diff --git a/src/bots/approved_bot/services/book_cache/mod.rs b/src/bots/approved_bot/services/book_cache/mod.rs index 5ac7767..47ce29d 100644 --- a/src/bots/approved_bot/services/book_cache/mod.rs +++ b/src/bots/approved_bot/services/book_cache/mod.rs @@ -43,7 +43,7 @@ pub async fn get_cached_message( pub async fn download_file( download_data: &DownloadQueryData, -) -> Result, Box> { +) -> anyhow::Result> { let DownloadQueryData::DownloadData { book_id: id, file_type: format, @@ -93,7 +93,7 @@ pub async fn download_file( pub async fn download_file_by_link( filename: String, link: String, -) -> Result, Box> { +) -> anyhow::Result> { let response = CLIENT.get(link).send().await?; if response.status() != StatusCode::OK { diff --git a/src/bots/approved_bot/services/book_library/mod.rs b/src/bots/approved_bot/services/book_library/mod.rs index ca3001b..30083bd 100644 --- a/src/bots/approved_bot/services/book_library/mod.rs +++ b/src/bots/approved_bot/services/book_library/mod.rs @@ -23,10 +23,7 @@ fn get_allowed_langs_params( .collect() } -async fn _make_request( - url: &str, - params: Vec<(&str, SmartString)>, -) -> Result> +async fn _make_request(url: &str, params: Vec<(&str, SmartString)>) -> anyhow::Result where T: DeserializeOwned, { @@ -42,19 +39,19 @@ where Ok(v) => Ok(v), Err(err) => { log::error!("Failed serialization: url={:?} err={:?}", url, err); - Err(Box::new(err)) + Err(err.into()) } } } -pub async fn get_book(id: u32) -> Result> { +pub async fn get_book(id: u32) -> anyhow::Result { _make_request(&format!("/api/v1/books/{id}"), vec![]).await } pub async fn get_random_book_by_genre( allowed_langs: SmallVec<[SmartString; 3]>, genre: Option, -) -> Result> { +) -> anyhow::Result { let mut params = get_allowed_langs_params(allowed_langs); if let Some(v) = genre { @@ -66,13 +63,13 @@ pub async fn get_random_book_by_genre( pub async fn get_random_book( allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result> { +) -> anyhow::Result { get_random_book_by_genre(allowed_langs, None).await } pub async fn get_random_author( allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result> { +) -> anyhow::Result { let params = get_allowed_langs_params(allowed_langs); _make_request("/api/v1/authors/random", params).await @@ -80,19 +77,17 @@ pub async fn get_random_author( pub async fn get_random_sequence( allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result> { +) -> anyhow::Result { let params = get_allowed_langs_params(allowed_langs); _make_request("/api/v1/sequences/random", params).await } -pub async fn get_genre_metas() -> Result, Box> { +pub async fn get_genre_metas() -> anyhow::Result> { _make_request("/api/v1/genres/metas", vec![]).await } -pub async fn get_genres( - meta: SmartString, -) -> Result, Box> { +pub async fn get_genres(meta: SmartString) -> anyhow::Result> { let params = vec![("meta", meta)]; _make_request("/api/v1/genres", params).await @@ -104,7 +99,7 @@ pub async fn search_book( query: String, page: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result, Box> { +) -> anyhow::Result> { let mut params = get_allowed_langs_params(allowed_langs); params.push(("page", page.to_string().into())); @@ -117,7 +112,7 @@ pub async fn search_author( query: String, page: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result, Box> { +) -> anyhow::Result> { let mut params = get_allowed_langs_params(allowed_langs); params.push(("page", page.to_string().into())); @@ -130,7 +125,7 @@ pub async fn search_sequence( query: String, page: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result, Box> { +) -> anyhow::Result> { let mut params = get_allowed_langs_params(allowed_langs); params.push(("page", page.to_string().into())); @@ -143,7 +138,7 @@ pub async fn search_translator( query: String, page: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result, Box> { +) -> anyhow::Result> { let mut params = get_allowed_langs_params(allowed_langs); params.push(("page", page.to_string().into())); @@ -156,15 +151,11 @@ pub async fn search_translator( .await } -pub async fn get_book_annotation( - id: u32, -) -> Result> { +pub async fn get_book_annotation(id: u32) -> anyhow::Result { _make_request(format!("/api/v1/books/{id}/annotation").as_str(), vec![]).await } -pub async fn get_author_annotation( - id: u32, -) -> Result> { +pub async fn get_author_annotation(id: u32) -> anyhow::Result { _make_request(format!("/api/v1/authors/{id}/annotation").as_str(), vec![]).await } @@ -172,10 +163,7 @@ pub async fn get_author_books( id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result< - types::Page, - Box, -> { +) -> anyhow::Result> { let mut params = get_allowed_langs_params(allowed_langs); params.push(("page", page.to_string().into())); @@ -188,10 +176,7 @@ pub async fn get_translator_books( id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result< - types::Page, - Box, -> { +) -> anyhow::Result> { let mut params = get_allowed_langs_params(allowed_langs); params.push(("page", page.to_string().into())); @@ -204,10 +189,7 @@ pub async fn get_sequence_books( id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result< - types::Page, - Box, -> { +) -> anyhow::Result> { let mut params = get_allowed_langs_params(allowed_langs); params.push(("page", page.to_string().into())); @@ -220,7 +202,7 @@ pub async fn get_uploaded_books( page: u32, uploaded_gte: SmartString, uploaded_lte: SmartString, -) -> Result, Box> { +) -> anyhow::Result> { let params = vec![ ("page", page.to_string().into()), ("size", PAGE_SIZE.to_string().into()), @@ -235,7 +217,7 @@ pub async fn get_uploaded_books( pub async fn get_author_books_available_types( id: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result, Box> { +) -> anyhow::Result> { let params = get_allowed_langs_params(allowed_langs); _make_request( @@ -248,7 +230,7 @@ pub async fn get_author_books_available_types( pub async fn get_translator_books_available_types( id: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result, Box> { +) -> anyhow::Result> { let params = get_allowed_langs_params(allowed_langs); _make_request( @@ -261,7 +243,7 @@ pub async fn get_translator_books_available_types( pub async fn get_sequence_books_available_types( id: u32, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result, Box> { +) -> anyhow::Result> { let params = get_allowed_langs_params(allowed_langs); _make_request( diff --git a/src/bots/approved_bot/services/user_settings/mod.rs b/src/bots/approved_bot/services/user_settings/mod.rs index d016816..6ae3fbf 100644 --- a/src/bots/approved_bot/services/user_settings/mod.rs +++ b/src/bots/approved_bot/services/user_settings/mod.rs @@ -79,7 +79,7 @@ pub async fn create_or_update_user_settings( username: String, source: String, allowed_langs: SmallVec<[SmartString; 3]>, -) -> Result> { +) -> anyhow::Result { USER_LANGS_CACHE.invalidate(&user_id).await; let body = json!({ @@ -103,7 +103,7 @@ pub async fn create_or_update_user_settings( Ok(response.json::().await?) } -pub async fn get_langs() -> Result, Box> { +pub async fn get_langs() -> anyhow::Result> { let response = CLIENT .get(format!("{}/languages/", &config::CONFIG.user_settings_url)) .header("Authorization", &config::CONFIG.user_settings_api_key) @@ -114,9 +114,7 @@ pub async fn get_langs() -> Result, Box>().await?) } -pub async fn update_user_activity( - user_id: UserId, -) -> Result<(), Box> { +pub async fn update_user_activity(user_id: UserId) -> anyhow::Result<()> { CLIENT .post(format!( "{}/users/{user_id}/update_activity", @@ -133,7 +131,7 @@ pub async fn update_user_activity( pub async fn is_need_donate_notifications( chat_id: ChatId, is_private: bool, -) -> Result> { +) -> anyhow::Result { let response = CLIENT .get(format!( "{}/donate_notifications/{chat_id}/is_need_send?is_private={is_private}", @@ -147,9 +145,7 @@ pub async fn is_need_donate_notifications( Ok(response.json::().await?) } -pub async fn mark_donate_notification_sent( - chat_id: ChatId, -) -> Result<(), Box> { +pub async fn mark_donate_notification_sent(chat_id: ChatId) -> anyhow::Result<()> { CLIENT .post(format!( "{}/donate_notifications/{chat_id}", diff --git a/src/bots/bots_manager/mod.rs b/src/bots/bots_manager/mod.rs index 7569119..c88fb4e 100644 --- a/src/bots/bots_manager/mod.rs +++ b/src/bots/bots_manager/mod.rs @@ -1,21 +1,17 @@ +use anyhow; use teloxide::{ adaptors::{CacheMe, Throttle}, prelude::*, types::ReplyParameters, }; -use std::error::Error; - use self::{strings::format_registered_message, utils::get_token}; pub mod register; pub mod strings; pub mod utils; -pub async fn message_handler( - message: Message, - bot: CacheMe>, -) -> Result<(), Box> { +pub async fn message_handler(message: Message, bot: CacheMe>) -> anyhow::Result<()> { let from_user = message.clone().from.unwrap(); let text = message.text().unwrap_or(""); @@ -35,11 +31,8 @@ pub async fn message_handler( Ok(()) } -pub fn get_manager_handler() -> Handler< - 'static, - Result<(), Box>, - teloxide::dispatching::DpHandlerDescription, -> { +pub fn get_manager_handler( +) -> Handler<'static, anyhow::Result<()>, teloxide::dispatching::DpHandlerDescription> { Update::filter_message().branch( Message::filter_text() .chain(dptree::filter(|message: Message| { diff --git a/src/bots/mod.rs b/src/bots/mod.rs index 504a8cf..3395f1d 100644 --- a/src/bots/mod.rs +++ b/src/bots/mod.rs @@ -1,11 +1,9 @@ mod approved_bot; pub mod bots_manager; -use std::error::Error; - use teloxide::prelude::*; -pub type BotHandlerInternal = Result<(), Box>; +pub type BotHandlerInternal = anyhow::Result<()>; type BotHandler = Handler<'static, BotHandlerInternal, teloxide::dispatching::DpHandlerDescription>; @@ -27,7 +25,7 @@ fn ignore_user_edited_message() -> crate::bots::BotHandler { dptree::entry().branch(Update::filter_edited_message().endpoint(|| async { Ok(()) })) } -fn ingore_chat_join_request() -> crate::bots::BotHandler { +fn ignore_chat_join_request() -> crate::bots::BotHandler { dptree::entry().branch(Update::filter_chat_join_request().endpoint(|| async { Ok(()) })) }