Skip to content

Commit b404bab

Browse files
fix: adapt to grammers API changes (Session::Error, fallible refs)
Recent grammers changes introduced an associated Error type on the Session trait and made several methods fallible: - SqliteSession::open now returns a SqliteSessionError. - SenderPool::new requires S::Error: std::error::Error + Send + Sync + 'static. - peer_ref, sender_ref, and Peer::to_ref now return Result<Option<PeerRef>, Box<dyn Error>>. - Client::stream_updates and UpdateStream::sync_update_state now return Result. Update the codebase accordingly and fix the from-env example. Verified: cargo check --all-targets, cargo test, cargo clippy --all-targets, cargo fmt --check.
1 parent a92df3e commit b404bab

5 files changed

Lines changed: 51 additions & 19 deletions

File tree

ferogram/examples/from-env.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use ferogram::prelude::ConnectionExt;
1515
use grammers::{Client, SenderPool, client::UpdatesConfiguration, update::Update};
1616
use tokio::{task::JoinSet, time::sleep};
1717

18+
type Result = std::result::Result<(), Box<dyn Error + Send + Sync>>;
19+
1820
async fn handle_update(client: Client, update: Update) {
1921
match update {
2022
Update::NewMessage(message) if !message.outgoing() => {
@@ -27,7 +29,7 @@ async fn handle_update(client: Client, update: Update) {
2729
sleep(Duration::from_secs(5)).await;
2830
}
2931
if let Err(e) = client
30-
.send_message(peer.to_ref().await.unwrap(), message.text())
32+
.send_message(peer.to_ref().await.unwrap().unwrap(), message.text())
3133
.await
3234
{
3335
println!("Failed to respond! {e}");
@@ -38,7 +40,7 @@ async fn handle_update(client: Client, update: Update) {
3840
}
3941

4042
#[tokio::main(flavor = "multi_thread")]
41-
async fn main() -> Result<(), Box<dyn Error>> {
43+
async fn main() -> Result {
4244
println!("Connecting...");
4345

4446
// Connect the client from environment variables.
@@ -65,7 +67,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
6567
..Default::default()
6668
},
6769
)
68-
.await;
70+
.await?;
6971

7072
loop {
7173
// Empty finished handlers (you could look at their return value here too.)
@@ -87,7 +89,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
8789
}
8890

8991
println!("Saving session file...");
90-
updates.sync_update_state().await;
92+
updates.sync_update_state().await?;
9193

9294
// Pool's `run()` won't finish until all handles are dropped or quit is called.
9395
// Here there are at least three handles alive: `handle`, `client` and `updates`

ferogram/src/client.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ pub trait ConnectionExt {
4646
api_id: i32,
4747
api_hash: &str,
4848
session: Arc<S>,
49-
) -> impl Future<Output = Result<(SenderPool, Client), ClientError>> + Send;
49+
) -> impl Future<Output = Result<(SenderPool, Client), ClientError>> + Send
50+
where
51+
S::Error: std::error::Error + Send + Sync + 'static;
5052

5153
/// Like [`Self::connect`] but with a custom [`ClientConfiguration`].
5254
fn connect_with_configuration<S: Session + 'static>(
@@ -55,7 +57,9 @@ pub trait ConnectionExt {
5557
api_hash: &str,
5658
session: Arc<S>,
5759
configuration: ClientConfiguration,
58-
) -> impl Future<Output = Result<(SenderPool, Client), ClientError>> + Send;
60+
) -> impl Future<Output = Result<(SenderPool, Client), ClientError>> + Send
61+
where
62+
S::Error: std::error::Error + Send + Sync + 'static;
5963
}
6064

6165
impl ConnectionExt for Client {
@@ -86,7 +90,11 @@ impl ConnectionExt for Client {
8690

8791
let session_path =
8892
std::env::var("SESSION_FILE").unwrap_or_else(|_| "grammers.session".to_string());
89-
let session = Arc::new(SqliteSession::open(session_path).await?);
93+
let session = Arc::new(
94+
SqliteSession::open(session_path)
95+
.await
96+
.map_err(|e| ClientError::SessionError(e.into()))?,
97+
);
9098

9199
let account = bot_token.unwrap_or_else(|_| phone_number.unwrap());
92100
Self::connect_with_configuration(&account, api_id, &api_hash, session, configuration).await
@@ -97,7 +105,10 @@ impl ConnectionExt for Client {
97105
api_id: i32,
98106
api_hash: &str,
99107
session: Arc<S>,
100-
) -> Result<(SenderPool, Self), ClientError> {
108+
) -> Result<(SenderPool, Self), ClientError>
109+
where
110+
S::Error: std::error::Error + Send + Sync + 'static,
111+
{
101112
Self::connect_with_configuration(account, api_id, api_hash, session, Default::default())
102113
.await
103114
}
@@ -108,7 +119,10 @@ impl ConnectionExt for Client {
108119
api_hash: &str,
109120
session: Arc<S>,
110121
configuration: ClientConfiguration,
111-
) -> Result<(SenderPool, Self), ClientError> {
122+
) -> Result<(SenderPool, Self), ClientError>
123+
where
124+
S::Error: std::error::Error + Send + Sync + 'static,
125+
{
112126
// Test session validity.
113127
{
114128
let SenderPool { runner, handle, .. } = SenderPool::new(Arc::clone(&session), api_id);

ferogram/src/context.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ impl Context {
5151
}
5252

5353
/// Cached reference to [`Self::peer`], if it is in cache.
54-
pub async fn peer_ref(&self) -> Option<PeerRef> {
54+
pub async fn peer_ref(
55+
&self,
56+
) -> Result<Option<PeerRef>, Box<dyn std::error::Error + Send + Sync>> {
5557
match &self.update {
5658
Update::NewMessage(message) | Update::MessageEdited(message) => {
5759
message.peer_ref().await
5860
}
5961
Update::CallbackQuery(query) => query.peer_ref().await,
60-
_ => None,
62+
_ => Ok(None),
6163
}
6264
}
6365

@@ -75,15 +77,17 @@ impl Context {
7577
}
7678

7779
/// Cached reference to [`Self::sender`], if it is in cache.
78-
pub async fn sender_ref(&self) -> Option<PeerRef> {
80+
pub async fn sender_ref(
81+
&self,
82+
) -> Result<Option<PeerRef>, Box<dyn std::error::Error + Send + Sync>> {
7983
match &self.update {
8084
Update::NewMessage(message) | Update::MessageEdited(message) => {
8185
message.sender_ref().await
8286
}
8387
Update::CallbackQuery(query) => query.sender_ref().await,
8488
Update::InlineQuery(query) => query.sender_ref().await,
8589
Update::InlineSend(send) => send.sender_ref().await,
86-
_ => None,
90+
_ => Ok(None),
8791
}
8892
}
8993

@@ -188,9 +192,9 @@ impl Context {
188192
}
189193

190194
/// Chat action sender.
191-
pub async fn action(&self) -> ActionSender {
192-
let peer = self.peer_ref().await.unwrap();
193-
self.client.action(peer)
195+
pub async fn action(&self) -> Result<ActionSender, InvocationError> {
196+
let peer = self.peer_ref().await?.unwrap();
197+
Ok(self.client.action(peer))
194198
}
195199

196200
/// Check if the peer is a group.
@@ -317,7 +321,7 @@ impl Context {
317321
///
318322
/// If the update is a [`CallbackQuery`], it will load the message first.
319323
pub async fn forward_to_self(&self) -> Result<Message, InvocationError> {
320-
let chat = self.client.get_me().await?.to_ref().await.unwrap();
324+
let chat = self.client.get_me().await?.to_ref().await?.unwrap();
321325

322326
self.forward_to(chat).await
323327
}

ferogram/src/dispatcher.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,15 @@ impl Dispatcher {
8888
let _guard = DispatcherExitGuard;
8989

9090
let mut handler_tasks = JoinSet::new();
91-
let mut updates = client.stream_updates(updates, configuration).await;
91+
let mut updates = match client.stream_updates(updates, configuration).await {
92+
Ok(updates) => updates,
93+
Err(e) => {
94+
tracing::error!("Failed to start update stream: {e}");
95+
handle.quit();
96+
let _ = pool_task.await;
97+
return;
98+
}
99+
};
92100

93101
loop {
94102
tokio::select! {
@@ -181,7 +189,9 @@ impl Dispatcher {
181189
}
182190

183191
tracing::info!("Saving session...");
184-
updates.sync_update_state().await;
192+
if let Err(e) = updates.sync_update_state().await {
193+
tracing::error!("Failed to save session: {e}");
194+
}
185195

186196
tracing::info!("Exiting...");
187197
handle.quit();

ferogram/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub enum ClientError {
1919
DatabaseError(#[from] libsql::Error),
2020
#[error("failed to establish connection to telegram: {0:?}")]
2121
ConnectionError(#[from] InvocationError),
22+
#[error("failed to use session: {0:?}")]
23+
SessionError(Box<dyn std::error::Error + Send + Sync>),
2224
#[error("variable `{0}` were expected, but none was found")]
2325
ExpectedVariable(String),
2426
}

0 commit comments

Comments
 (0)