diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b395c54..8fd4dcc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add `MessageToCopyNotFound` error to `teloxide::errors::ApiError` ([PR 917](https://github.com/teloxide/teloxide/pull/917)) +- `Dispatcher::try_dispatch_with_listener` ([PR 913](https://github.com/teloxide/teloxide/pull/913)) ### Fixed diff --git a/crates/teloxide/src/dispatching/dispatcher.rs b/crates/teloxide/src/dispatching/dispatcher.rs index 4629c3fe..91db674a 100644 --- a/crates/teloxide/src/dispatching/dispatcher.rs +++ b/crates/teloxide/src/dispatching/dispatcher.rs @@ -277,7 +277,6 @@ where /// - An update from Telegram; /// - [`crate::types::Me`] (can be used in [`HandlerExt::filter_command`]). /// - /// [`shutdown`]: ShutdownToken::shutdown /// [`HandlerExt::filter_command`]: crate::dispatching::HandlerExt::filter_command pub async fn dispatch(&mut self) where @@ -295,19 +294,39 @@ where /// `update_listener_error_handler`. /// /// This method adds the same dependencies as [`Dispatcher::dispatch`]. - /// - /// [`shutdown`]: ShutdownToken::shutdown pub async fn dispatch_with_listener<'a, UListener, Eh>( &'a mut self, - mut update_listener: UListener, + update_listener: UListener, update_listener_error_handler: Arc, ) where UListener: UpdateListener + 'a, Eh: ErrorHandler + 'a, UListener::Err: Debug, + { + self.try_dispatch_with_listener(update_listener, update_listener_error_handler) + .await + .expect("Couldn't prepare dispatching context") + } + + /// Same as `dispatch_with_listener` but returns a `Err(_)` instead of + /// panicking when the initial telegram api call (`get_me`) fails. + /// + /// Starts your bot with custom `update_listener` and + /// `update_listener_error_handler`. + /// + /// This method adds the same dependencies as [`Dispatcher::dispatch`]. + pub async fn try_dispatch_with_listener<'a, UListener, Eh>( + &'a mut self, + mut update_listener: UListener, + update_listener_error_handler: Arc, + ) -> Result<(), R::Err> + where + UListener: UpdateListener + 'a, + Eh: ErrorHandler + 'a, + UListener::Err: Debug, { // FIXME: there should be a way to check if dependency is already inserted - let me = self.bot.get_me().send().await.expect("Failed to retrieve 'me'"); + let me = self.bot.get_me().send().await?; self.dependencies.insert(me); self.dependencies.insert(self.bot.clone()); @@ -360,6 +379,7 @@ where .await; self.state.done(); + Ok(()) } async fn process_update( @@ -462,9 +482,8 @@ where } } - /// Setups the `^C` handler that [`shutdown`]s dispatching. - /// - /// [`shutdown`]: ShutdownToken::shutdown + /// Setups the `^C` handler in order to call [`ShutdownToken::shutdown`] + /// when pressed. #[cfg(feature = "ctrlc_handler")] #[deprecated(since = "0.10.0", note = "use `enable_ctrlc_handler` on builder instead")] pub fn setup_ctrlc_handler(&mut self) -> &mut Self { @@ -472,8 +491,8 @@ where self } - /// Returns a shutdown token, which can later be used to shutdown - /// dispatching. + /// Returns a shutdown token, which can later be used to + /// [`ShutdownToken::shutdown`]. pub fn shutdown_token(&self) -> ShutdownToken { self.state.clone() }