mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
It could be the brother of Option<Vec<T>>..
This commit is contained in:
parent
a8d490d0ae
commit
93aa829543
3 changed files with 31 additions and 49 deletions
|
@ -59,29 +59,18 @@ async fn main() {
|
|||
.await;
|
||||
}
|
||||
|
||||
async fn error_handler(error: PublicError, deps: Option<DependencyMap>) {
|
||||
async fn error_handler(error: PublicError, deps: DependencyMap) {
|
||||
/*
|
||||
When the error is returned from one of the handlers, deps will contain actual initial_dependencies
|
||||
|
||||
In this example it's not valuable to handle errors with no dependencies, so just log them and ignore
|
||||
*/
|
||||
if deps.is_none() {
|
||||
log::error!("Error occured: {}", error);
|
||||
return;
|
||||
}
|
||||
let deps = deps.unwrap();
|
||||
|
||||
/*
|
||||
The Bot is always present in the dependencies, so it's safe to query it here
|
||||
|
||||
Note that you can access only initial dependencies, such as:
|
||||
- Bot
|
||||
- Update
|
||||
- Me
|
||||
- and the ones you've provided to the Dispatcher's dependencies
|
||||
When an error is occured in one of your handlers, you can access only initial dependencies, such as:
|
||||
- Update
|
||||
- Bot
|
||||
- Me
|
||||
- and the ones you've provided to the Dispatcher's dependencies at the beginning
|
||||
*/
|
||||
|
||||
let bot: Arc<Bot> = deps.get();
|
||||
// It worth to note that in case of UpdateListener::Error there will be no
|
||||
// Update value
|
||||
let update: Arc<Update> = deps.get();
|
||||
let chat_id = update.chat().map(|c| c.id);
|
||||
|
||||
|
@ -89,7 +78,7 @@ async fn error_handler(error: PublicError, deps: Option<DependencyMap>) {
|
|||
PublicError::Dummy => {
|
||||
// Some updates don't have a chat id
|
||||
if let Some(chat_id) = chat_id {
|
||||
// TODO, maybe retry queue?
|
||||
// TODO, maybe retry queue? backon?
|
||||
let _ = bot.send_message(chat_id, error.to_string()).await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -492,7 +492,7 @@ where
|
|||
|
||||
worker.tx.send(upd).await.expect("TX is dead");
|
||||
}
|
||||
Err(err) => err_handler.clone().handle_error(err, None).await,
|
||||
Err(err) => err_handler.clone().handle_error(err, self.dependencies.clone()).await,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -649,7 +649,7 @@ async fn handle_update<Err>(
|
|||
|
||||
match handler.dispatch(deps.clone()).await {
|
||||
ControlFlow::Break(Ok(())) => {}
|
||||
ControlFlow::Break(Err(err)) => error_handler.clone().handle_error(err, Some(deps)).await,
|
||||
ControlFlow::Break(Err(err)) => error_handler.clone().handle_error(err, deps).await,
|
||||
ControlFlow::Continue(deps) => {
|
||||
let update = deps.get();
|
||||
(default_handler)(update).await;
|
||||
|
|
|
@ -11,24 +11,16 @@ use futures::future::BoxFuture;
|
|||
/// overview](crate::dispatching).
|
||||
pub trait ErrorHandler<E> {
|
||||
#[must_use]
|
||||
fn handle_error(
|
||||
self: Arc<Self>,
|
||||
error: E,
|
||||
deps: Option<DependencyMap>,
|
||||
) -> BoxFuture<'static, ()>;
|
||||
fn handle_error(self: Arc<Self>, error: E, deps: DependencyMap) -> BoxFuture<'static, ()>;
|
||||
}
|
||||
|
||||
impl<E, F, Fut> ErrorHandler<E> for F
|
||||
where
|
||||
F: Fn(E, Option<DependencyMap>) -> Fut + Send + Sync + 'static,
|
||||
F: Fn(E, DependencyMap) -> Fut + Send + Sync + 'static,
|
||||
E: Send + 'static,
|
||||
Fut: Future<Output = ()> + Send,
|
||||
{
|
||||
fn handle_error(
|
||||
self: Arc<Self>,
|
||||
error: E,
|
||||
deps: Option<DependencyMap>,
|
||||
) -> BoxFuture<'static, ()> {
|
||||
fn handle_error(self: Arc<Self>, error: E, deps: DependencyMap) -> BoxFuture<'static, ()> {
|
||||
Box::pin(async move { self(error, deps).await })
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +85,7 @@ where
|
|||
{
|
||||
Box::pin(async move {
|
||||
if let Err(error) = self {
|
||||
eh.handle_error(error, None).await;
|
||||
eh.handle_error(error, DependencyMap::new()).await;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -108,9 +100,9 @@ where
|
|||
/// use dptree::di::DependencyMap;
|
||||
/// use teloxide::error_handlers::{ErrorHandler, IgnoringErrorHandler};
|
||||
///
|
||||
/// IgnoringErrorHandler::new().handle_error((), None).await;
|
||||
/// IgnoringErrorHandler::new().handle_error(404, None).await;
|
||||
/// IgnoringErrorHandler::new().handle_error("error", None).await;
|
||||
/// IgnoringErrorHandler::new().handle_error((), DependencyMap::new()).await;
|
||||
/// IgnoringErrorHandler::new().handle_error(404, DependencyMap::new()).await;
|
||||
/// IgnoringErrorHandler::new().handle_error("error", DependencyMap::new()).await;
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -124,7 +116,7 @@ impl IgnoringErrorHandler {
|
|||
}
|
||||
|
||||
impl<E> ErrorHandler<E> for IgnoringErrorHandler {
|
||||
fn handle_error(self: Arc<Self>, _: E, _: Option<DependencyMap>) -> BoxFuture<'static, ()> {
|
||||
fn handle_error(self: Arc<Self>, _: E, _: DependencyMap) -> BoxFuture<'static, ()> {
|
||||
Box::pin(async {})
|
||||
}
|
||||
}
|
||||
|
@ -138,15 +130,17 @@ impl<E> ErrorHandler<E> for IgnoringErrorHandler {
|
|||
/// # async fn main_() {
|
||||
/// use std::convert::{Infallible, TryInto};
|
||||
///
|
||||
/// use dptree::di::DependencyMap;
|
||||
/// use teloxide::error_handlers::{ErrorHandler, IgnoringErrorHandlerSafe};
|
||||
///
|
||||
/// let result: Result<String, Infallible> = "str".try_into();
|
||||
/// match result {
|
||||
/// Ok(string) => println!("{}", string),
|
||||
/// Err(inf) => IgnoringErrorHandlerSafe::new().handle_error(inf, None).await,
|
||||
/// Err(inf) => IgnoringErrorHandlerSafe::new().handle_error(inf, DependencyMap::new()).await,
|
||||
/// }
|
||||
///
|
||||
/// IgnoringErrorHandlerSafe::new().handle_error(return, None).await; // return type of `return` is `!` (aka never)
|
||||
/// IgnoringErrorHandlerSafe::new().handle_error(return, DependencyMap::new()).await;
|
||||
/// // return type of `return` is `!` (aka never)
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
|
@ -170,11 +164,7 @@ impl IgnoringErrorHandlerSafe {
|
|||
|
||||
#[allow(unreachable_code)]
|
||||
impl ErrorHandler<Infallible> for IgnoringErrorHandlerSafe {
|
||||
fn handle_error(
|
||||
self: Arc<Self>,
|
||||
_: Infallible,
|
||||
_: Option<DependencyMap>,
|
||||
) -> BoxFuture<'static, ()> {
|
||||
fn handle_error(self: Arc<Self>, _: Infallible, _: DependencyMap) -> BoxFuture<'static, ()> {
|
||||
Box::pin(async {})
|
||||
}
|
||||
}
|
||||
|
@ -185,11 +175,14 @@ impl ErrorHandler<Infallible> for IgnoringErrorHandlerSafe {
|
|||
/// ```
|
||||
/// # #[tokio::main]
|
||||
/// # async fn main_() {
|
||||
/// use dptree::di::DependencyMap;
|
||||
/// use teloxide::error_handlers::{ErrorHandler, LoggingErrorHandler};
|
||||
///
|
||||
/// LoggingErrorHandler::new().handle_error((), None).await;
|
||||
/// LoggingErrorHandler::with_custom_text("Omg1").handle_error(404, None).await;
|
||||
/// LoggingErrorHandler::with_custom_text("Omg2").handle_error("Invalid data type!", None).await;
|
||||
/// LoggingErrorHandler::new().handle_error((), DependencyMap::new()).await;
|
||||
/// LoggingErrorHandler::with_custom_text("Omg1").handle_error(404, DependencyMap::new()).await;
|
||||
/// LoggingErrorHandler::with_custom_text("Omg2")
|
||||
/// .handle_error("Invalid data type!", DependencyMap::new())
|
||||
/// .await;
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct LoggingErrorHandler {
|
||||
|
@ -220,7 +213,7 @@ impl<E> ErrorHandler<E> for LoggingErrorHandler
|
|||
where
|
||||
E: Debug,
|
||||
{
|
||||
fn handle_error(self: Arc<Self>, error: E, _: Option<DependencyMap>) -> BoxFuture<'static, ()> {
|
||||
fn handle_error(self: Arc<Self>, error: E, _: DependencyMap) -> BoxFuture<'static, ()> {
|
||||
log::error!("{text}: {:?}", error, text = self.text);
|
||||
Box::pin(async {})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue