botx_api/api/utils/
auth_retry.rs1use std::sync::Arc;
2
3use async_lock::RwLock;
4use log::{error, info};
5
6use crate::api::{
7 context::BotXApiContext,
8 result::{BotXApiError, BotXApiResult},
9 v2::token::api::token,
10};
11
12use std::future::Future;
13
14pub async fn retry_with_auth<Fut, TResponse, TError, TRequest: Fn() -> Fut>(
15 context: &Arc<RwLock<BotXApiContext>>,
16 request: TRequest,
17) -> Result<TResponse, BotXApiError<TError>>
18where
19 Fut: Future<Output = BotXApiResult<TResponse, TError>>,
22{
23 let response = (request)().await;
24
25 let Err(err) = response else {
26 return response
27 };
28
29 if !err.is_unauthorized() {
30 return Result::<TResponse, BotXApiError<TError>>::Err(err);
31 }
32
33 info!("Действие токена истекло, презапрашиваем");
34
35 let mut context_write_lock = context.write().await;
36 let token_response = token(&mut *context_write_lock).await;
37
38 let Ok(token_result) = token_response else {
39 error!("Не удалось повторить запрос с переавторизацией");
40 return Result::<TResponse, BotXApiError<TError>>::Err(err);
41 };
42
43 context_write_lock.auth_token = Some(token_result.token);
44
45 (request)().await
46}