fix: eliminate infinite recursion in TdClientTrait implementation
CRITICAL BUG FIX: Three methods in TdClientTrait impl were calling themselves recursively instead of delegating to actual implementations, causing stack overflow and application panic on startup.
Fixed methods:
1. user_cache_mut() - now returns &mut self.user_cache directly
2. sync_notification_muted_chats() - now delegates to notification_manager.sync_muted_chats()
3. handle_update() - now properly delegates to TdClient::handle_update() using qualified path
This bug caused the app to hang on "Инициализация TDLib..." screen and exit raw mode, displaying escape sequences ("CB52") on key presses when user tried to interact.
Root cause: Introduced in refactoring commit bd5e5be where trait implementations were created but incorrectly delegated to self.method() instead of accessing struct fields directly or using qualified path syntax.
Also added panic hook in main.rs to ensure terminal restoration on panic for better debugging experience.
Impact: Application completely broken - couldn't start. Stack overflow on first update.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
14
src/main.rs
14
src/main.rs
@@ -55,14 +55,22 @@ async fn main() -> Result<(), io::Error> {
|
|||||||
let backend = CrosstermBackend::new(stdout);
|
let backend = CrosstermBackend::new(stdout);
|
||||||
let mut terminal = Terminal::new(backend)?;
|
let mut terminal = Terminal::new(backend)?;
|
||||||
|
|
||||||
|
// Ensure terminal restoration on panic
|
||||||
|
let panic_hook = std::panic::take_hook();
|
||||||
|
std::panic::set_hook(Box::new(move |info| {
|
||||||
|
let _ = disable_raw_mode();
|
||||||
|
let _ = execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture);
|
||||||
|
panic_hook(info);
|
||||||
|
}));
|
||||||
|
|
||||||
// Create app state
|
// Create app state
|
||||||
let mut app = App::new(config);
|
let mut app = App::new(config);
|
||||||
|
|
||||||
// Запускаем инициализацию TDLib в фоне (только для реального клиента)
|
// Запускаем инициализацию TDLib в фоне (только для реального клиента)
|
||||||
let client_id = app.td_client.client_id();
|
let client_id = app.td_client.client_id();
|
||||||
let api_id = app.td_client.api_id;
|
let api_id = app.td_client.api_id;
|
||||||
let api_hash = app.td_client.api_hash.clone();
|
let api_hash = app.td_client.api_hash.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let _ = tdlib_rs::functions::set_tdlib_parameters(
|
let _ = tdlib_rs::functions::set_tdlib_parameters(
|
||||||
false, // use_test_dc
|
false, // use_test_dc
|
||||||
@@ -83,7 +91,7 @@ async fn main() -> Result<(), io::Error> {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = run_app(&mut terminal, &mut app).await;
|
let res = run_app(&mut terminal, &mut app).await;
|
||||||
|
|
||||||
// Restore terminal
|
// Restore terminal
|
||||||
|
|||||||
@@ -260,16 +260,17 @@ impl TdClientTrait for TdClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn user_cache_mut(&mut self) -> &mut UserCache {
|
fn user_cache_mut(&mut self) -> &mut UserCache {
|
||||||
self.user_cache_mut()
|
&mut self.user_cache
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ Notification methods ============
|
// ============ Notification methods ============
|
||||||
fn sync_notification_muted_chats(&mut self) {
|
fn sync_notification_muted_chats(&mut self) {
|
||||||
self.sync_notification_muted_chats()
|
self.notification_manager.sync_muted_chats(&self.chat_manager.chats);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ Update handling ============
|
// ============ Update handling ============
|
||||||
fn handle_update(&mut self, update: Update) {
|
fn handle_update(&mut self, update: Update) {
|
||||||
self.handle_update(update)
|
// Delegate to the real implementation
|
||||||
|
TdClient::handle_update(self, update)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user