Handle data parsing errors in ContactsManager.

This commit is contained in:
levlam 2023-03-08 19:15:51 +03:00
parent 57a3773fd6
commit e45eaa9939

View File

@ -6395,9 +6395,13 @@ void ContactsManager::on_load_imported_contacts_from_database(string value) {
if (value.empty()) { if (value.empty()) {
CHECK(all_imported_contacts_.empty()); CHECK(all_imported_contacts_.empty());
} else { } else {
log_event_parse(all_imported_contacts_, value).ensure(); if (log_event_parse(all_imported_contacts_, value).is_error()) {
LOG(ERROR) << "Failed to load all imported contacts from database";
all_imported_contacts_.clear();
} else {
LOG(INFO) << "Successfully loaded " << all_imported_contacts_.size() << " imported contacts from database"; LOG(INFO) << "Successfully loaded " << all_imported_contacts_.size() << " imported contacts from database";
} }
}
load_imported_contact_users_multipromise_.add_promise( load_imported_contact_users_multipromise_.add_promise(
PromiseCreator::lambda([actor_id = actor_id(this)](Result<Unit> result) { PromiseCreator::lambda([actor_id = actor_id(this)](Result<Unit> result) {
@ -9655,7 +9659,11 @@ void ContactsManager::on_load_contacts_from_database(string value) {
} }
vector<UserId> user_ids; vector<UserId> user_ids;
log_event_parse(user_ids, value).ensure(); if (log_event_parse(user_ids, value).is_error()) {
LOG(ERROR) << "Failed to load contacts from database";
reload_contacts(true);
return;
}
LOG(INFO) << "Successfully loaded " << user_ids.size() << " contacts from database"; LOG(INFO) << "Successfully loaded " << user_ids.size() << " contacts from database";
@ -10034,7 +10042,11 @@ void ContactsManager::on_binlog_user_event(BinlogEvent &&event) {
} }
UserLogEvent log_event; UserLogEvent log_event;
log_event_parse(log_event, event.get_data()).ensure(); if (log_event_parse(log_event, event.get_data()).is_error()) {
LOG(ERROR) << "Failed to load a user from binlog";
binlog_erase(G()->td_db()->get_binlog(), event.id_);
return;
}
auto user_id = log_event.user_id; auto user_id = log_event.user_id;
if (have_min_user(user_id) || !user_id.is_valid()) { if (have_min_user(user_id) || !user_id.is_valid()) {
@ -10175,12 +10187,15 @@ void ContactsManager::on_load_user_from_database(UserId user_id, string value, b
if (!value.empty()) { if (!value.empty()) {
u = add_user(user_id, "on_load_user_from_database"); u = add_user(user_id, "on_load_user_from_database");
log_event_parse(*u, value).ensure(); if (log_event_parse(*u, value).is_error()) {
LOG(ERROR) << "Failed to load " << user_id << " from database";
users_.erase(user_id);
} else {
u->is_saved = true; u->is_saved = true;
u->is_status_saved = true; u->is_status_saved = true;
update_user(u, user_id, true, true); update_user(u, user_id, true, true);
} }
}
} else { } else {
CHECK(!u->is_saved); // user can't be saved before load completes CHECK(!u->is_saved); // user can't be saved before load completes
CHECK(!u->is_being_saved); CHECK(!u->is_being_saved);
@ -10358,7 +10373,11 @@ void ContactsManager::on_binlog_chat_event(BinlogEvent &&event) {
} }
ChatLogEvent log_event; ChatLogEvent log_event;
log_event_parse(log_event, event.get_data()).ensure(); if (log_event_parse(log_event, event.get_data()).is_error()) {
LOG(ERROR) << "Failed to load a basic group from binlog";
binlog_erase(G()->td_db()->get_binlog(), event.id_);
return;
}
auto chat_id = log_event.chat_id; auto chat_id = log_event.chat_id;
if (have_chat(chat_id) || !chat_id.is_valid()) { if (have_chat(chat_id) || !chat_id.is_valid()) {
@ -10492,11 +10511,14 @@ void ContactsManager::on_load_chat_from_database(ChatId chat_id, string value, b
if (!value.empty()) { if (!value.empty()) {
c = add_chat(chat_id); c = add_chat(chat_id);
log_event_parse(*c, value).ensure(); if (log_event_parse(*c, value).is_error()) {
LOG(ERROR) << "Failed to load " << chat_id << " from database";
chats_.erase(chat_id);
} else {
c->is_saved = true; c->is_saved = true;
update_chat(c, chat_id, true, true); update_chat(c, chat_id, true, true);
} }
}
} else { } else {
CHECK(!c->is_saved); // chat can't be saved before load completes CHECK(!c->is_saved); // chat can't be saved before load completes
CHECK(!c->is_being_saved); CHECK(!c->is_being_saved);
@ -10597,7 +10619,11 @@ void ContactsManager::on_binlog_channel_event(BinlogEvent &&event) {
} }
ChannelLogEvent log_event; ChannelLogEvent log_event;
log_event_parse(log_event, event.get_data()).ensure(); if (log_event_parse(log_event, event.get_data()).is_error()) {
LOG(ERROR) << "Failed to load a supergroup from binlog";
binlog_erase(G()->td_db()->get_binlog(), event.id_);
return;
}
auto channel_id = log_event.channel_id; auto channel_id = log_event.channel_id;
if (have_channel(channel_id) || !channel_id.is_valid()) { if (have_channel(channel_id) || !channel_id.is_valid()) {
@ -10732,17 +10758,20 @@ void ContactsManager::on_load_channel_from_database(ChannelId channel_id, string
if (!value.empty()) { if (!value.empty()) {
c = add_channel(channel_id, "on_load_channel_from_database"); c = add_channel(channel_id, "on_load_channel_from_database");
log_event_parse(*c, value).ensure(); if (log_event_parse(*c, value).is_error()) {
LOG(ERROR) << "Failed to load " << channel_id << " from database";
channels_.erase(channel_id);
} else {
c->is_saved = true; c->is_saved = true;
update_channel(c, channel_id, true, true); update_channel(c, channel_id, true, true);
} }
}
} else { } else {
CHECK(!c->is_saved); // channel can't be saved before load completes CHECK(!c->is_saved); // channel can't be saved before load completes
CHECK(!c->is_being_saved); CHECK(!c->is_being_saved);
if (!value.empty()) { if (!value.empty()) {
Channel temp_c; Channel temp_c;
log_event_parse(temp_c, value).ensure(); if (log_event_parse(temp_c, value).is_ok()) {
if (c->participant_count == 0 && temp_c.participant_count != 0) { if (c->participant_count == 0 && temp_c.participant_count != 0) {
c->participant_count = temp_c.participant_count; c->participant_count = temp_c.participant_count;
CHECK(c->is_update_supergroup_sent); CHECK(c->is_update_supergroup_sent);
@ -10762,6 +10791,7 @@ void ContactsManager::on_load_channel_from_database(ChannelId channel_id, string
CHECK(!c->is_being_saved); CHECK(!c->is_being_saved);
} }
} }
}
auto new_value = get_channel_database_value(c); auto new_value = get_channel_database_value(c);
if (value != new_value) { if (value != new_value) {
save_channel_to_database_impl(c, channel_id, std::move(new_value)); save_channel_to_database_impl(c, channel_id, std::move(new_value));
@ -10852,7 +10882,11 @@ void ContactsManager::on_binlog_secret_chat_event(BinlogEvent &&event) {
} }
SecretChatLogEvent log_event; SecretChatLogEvent log_event;
log_event_parse(log_event, event.get_data()).ensure(); if (log_event_parse(log_event, event.get_data()).is_error()) {
LOG(ERROR) << "Failed to load a secret chat from binlog";
binlog_erase(G()->td_db()->get_binlog(), event.id_);
return;
}
auto secret_chat_id = log_event.secret_chat_id; auto secret_chat_id = log_event.secret_chat_id;
if (have_secret_chat(secret_chat_id) || !secret_chat_id.is_valid()) { if (have_secret_chat(secret_chat_id) || !secret_chat_id.is_valid()) {
@ -10989,11 +11023,14 @@ void ContactsManager::on_load_secret_chat_from_database(SecretChatId secret_chat
if (!value.empty()) { if (!value.empty()) {
c = add_secret_chat(secret_chat_id); c = add_secret_chat(secret_chat_id);
log_event_parse(*c, value).ensure(); if (log_event_parse(*c, value).is_error()) {
LOG(ERROR) << "Failed to load " << secret_chat_id << " from database";
secret_chats_.erase(secret_chat_id);
} else {
c->is_saved = true; c->is_saved = true;
update_secret_chat(c, secret_chat_id, true, true); update_secret_chat(c, secret_chat_id, true, true);
} }
}
} else { } else {
CHECK(!c->is_saved); // secret chat can't be saved before load completes CHECK(!c->is_saved); // secret chat can't be saved before load completes
CHECK(!c->is_being_saved); CHECK(!c->is_being_saved);
@ -17362,7 +17399,9 @@ void ContactsManager::on_load_dialog_administrators_from_database(
} }
vector<DialogAdministrator> administrators; vector<DialogAdministrator> administrators;
log_event_parse(administrators, value).ensure(); if (log_event_parse(administrators, value).is_error()) {
return reload_dialog_administrators(dialog_id, {}, std::move(promise));
}
LOG(INFO) << "Successfully loaded " << administrators.size() << " administrators in " << dialog_id LOG(INFO) << "Successfully loaded " << administrators.size() << " administrators in " << dialog_id
<< " from database"; << " from database";