fix some crashes, mostly related to network requests (#6187)

This commit is contained in:
pajlada
2025-05-17 14:22:56 +02:00
committed by GitHub
parent 46f3299a25
commit 6b968a199c
17 changed files with 259 additions and 81 deletions
+35 -23
View File
@@ -1,5 +1,6 @@
#include "providers/recentmessages/Api.hpp"
#include "Application.hpp"
#include "common/network/NetworkRequest.hpp"
#include "common/network/NetworkResult.hpp"
#include "common/QLogging.hpp"
@@ -33,8 +34,15 @@ void load(
const long delayMs = jitter ? std::rand() % 100 : 0;
QTimer::singleShot(delayMs, [=] {
if (isAppAboutToQuit())
{
return;
}
NetworkRequest(url)
.onSuccess([channelPtr, onLoaded](const auto &result) {
assert(!isAppAboutToQuit());
auto shared = channelPtr.lock();
if (!shared)
{
@@ -51,30 +59,33 @@ void load(
auto builtMessages =
buildRecentMessages(parsedMessages, shared.get());
postToThread([shared = std::move(shared),
root = std::move(root),
messages = std::move(builtMessages),
onLoaded]() mutable {
// Notify user about a possible gap in logs if it returned some messages
// but isn't currently joined to a channel
const auto errorCode = root.value("error_code").toString();
if (!errorCode.isEmpty())
{
qCDebug(LOG)
<< QString("Got error from API: error_code=%1, "
"channel=%2")
.arg(errorCode, shared->getName());
if (errorCode == "channel_not_joined" &&
!messages.empty())
{
shared->addSystemMessage(
"Message history service recovering, there may "
"be gaps in the message history.");
}
}
postToThread(
[shared = std::move(shared), root = std::move(root),
messages = std::move(builtMessages), onLoaded]() mutable {
assert(!isAppAboutToQuit());
onLoaded(messages);
});
// Notify user about a possible gap in logs if it returned some messages
// but isn't currently joined to a channel
const auto errorCode =
root.value("error_code").toString();
if (!errorCode.isEmpty())
{
qCDebug(LOG)
<< QString("Got error from API: error_code=%1, "
"channel=%2")
.arg(errorCode, shared->getName());
if (errorCode == "channel_not_joined" &&
!messages.empty())
{
shared->addSystemMessage(
"Message history service recovering, there "
"may "
"be gaps in the message history.");
}
}
onLoaded(messages);
});
})
.onError([channelPtr, onError](const NetworkResult &result) {
auto shared = channelPtr.lock();
@@ -82,6 +93,7 @@ void load(
{
return;
}
assert(!isAppAboutToQuit());
qCDebug(LOG) << "Failed to load recent messages for"
<< shared->getName();
+2
View File
@@ -440,6 +440,8 @@ void SeventvEmotes::getEmoteSet(
getApp()->getSeventvAPI()->getEmoteSet(
emoteSetId,
[callback = std::move(successCallback), emoteSetId](const auto &json) {
assert(!isAppAboutToQuit());
auto parsedEmotes = json["emotes"].toArray();
auto emoteMap = parseEmotes(parsedEmotes, false);
+2 -2
View File
@@ -106,13 +106,13 @@ ChannelPointReward::ChannelPointReward(const QJsonObject &redemption)
}
else
{
static const ImageSet defaultImage{
static const ImageSet *defaultImage = new ImageSet{
Image::fromUrl({twitchChannelPointRewardUrl("1.png")}, 1, baseSize),
Image::fromUrl({twitchChannelPointRewardUrl("2.png")}, 0.5,
baseSize * 2),
Image::fromUrl({twitchChannelPointRewardUrl("4.png")}, 0.25,
baseSize * 4)};
this->image = defaultImage;
this->image = *defaultImage;
}
}
+1
View File
@@ -1381,6 +1381,7 @@ void TwitchChannel::loadRecentMessages()
recentmessages::load(
this->getName(), weak,
[weak](const auto &messages) {
assert(!isAppAboutToQuit());
auto shared = weak.lock();
if (!shared)
{
+66 -42
View File
@@ -254,6 +254,11 @@ void TwitchIrcServer::initialize()
auto reward = ChannelPointReward(data);
postToThread([chan, reward] {
if (isAppAboutToQuit())
{
return;
}
if (auto *channel = dynamic_cast<TwitchChannel *>(chan.get()))
{
channel->addChannelPointReward(reward);
@@ -262,6 +267,13 @@ void TwitchIrcServer::initialize()
});
}
void TwitchIrcServer::aboutToQuit()
{
this->signalHolder.clear();
this->channels.clear();
}
void TwitchIrcServer::initializeConnection(IrcConnection *connection,
ConnectionType type)
{
@@ -550,8 +562,8 @@ std::shared_ptr<Channel> TwitchIrcServer::getCustomChannel(
return this->automodChannel;
}
static auto getTimer = [](ChannelPtr channel, int msBetweenMessages,
bool addInitialMessages) {
static auto getTimer = [this](ChannelPtr channel, int msBetweenMessages,
bool addInitialMessages) {
if (addInitialMessages)
{
for (auto i = 0; i < 1000; i++)
@@ -561,7 +573,7 @@ std::shared_ptr<Channel> TwitchIrcServer::getCustomChannel(
}
auto *timer = new QTimer;
QObject::connect(timer, &QTimer::timeout, [channel] {
QObject::connect(timer, &QTimer::timeout, this, [channel] {
channel->addSystemMessage(QTime::currentTime().toString());
});
timer->start(msBetweenMessages);
@@ -841,37 +853,43 @@ void TwitchIrcServer::initEventAPIs(BttvLiveUpdates *bttvLiveUpdates,
bttvLiveUpdates->signals_.emoteAdded, [&](const auto &data) {
auto chan = this->getChannelOrEmptyByID(data.channelID);
postToThread([chan, data] {
if (auto *channel =
dynamic_cast<TwitchChannel *>(chan.get()))
{
channel->addBttvEmote(data);
}
});
postToThread(
[chan, data] {
if (auto *channel =
dynamic_cast<TwitchChannel *>(chan.get()))
{
channel->addBttvEmote(data);
}
},
this);
});
this->signalHolder.managedConnect(
bttvLiveUpdates->signals_.emoteUpdated, [&](const auto &data) {
auto chan = this->getChannelOrEmptyByID(data.channelID);
postToThread([chan, data] {
if (auto *channel =
dynamic_cast<TwitchChannel *>(chan.get()))
{
channel->updateBttvEmote(data);
}
});
postToThread(
[chan, data] {
if (auto *channel =
dynamic_cast<TwitchChannel *>(chan.get()))
{
channel->updateBttvEmote(data);
}
},
this);
});
this->signalHolder.managedConnect(
bttvLiveUpdates->signals_.emoteRemoved, [&](const auto &data) {
auto chan = this->getChannelOrEmptyByID(data.channelID);
postToThread([chan, data] {
if (auto *channel =
dynamic_cast<TwitchChannel *>(chan.get()))
{
channel->removeBttvEmote(data);
}
});
postToThread(
[chan, data] {
if (auto *channel =
dynamic_cast<TwitchChannel *>(chan.get()))
{
channel->removeBttvEmote(data);
}
},
this);
});
bttvLiveUpdates->start();
@@ -886,30 +904,36 @@ void TwitchIrcServer::initEventAPIs(BttvLiveUpdates *bttvLiveUpdates,
{
this->signalHolder.managedConnect(
seventvEventAPI->signals_.emoteAdded, [this](const auto &data) {
postToThread([this, data] {
this->forEachSeventvEmoteSet(data.emoteSetID,
[data](TwitchChannel &chan) {
chan.addSeventvEmote(data);
});
});
postToThread(
[this, data] {
this->forEachSeventvEmoteSet(
data.emoteSetID, [data](TwitchChannel &chan) {
chan.addSeventvEmote(data);
});
},
this);
});
this->signalHolder.managedConnect(
seventvEventAPI->signals_.emoteUpdated, [this](const auto &data) {
postToThread([this, data] {
this->forEachSeventvEmoteSet(
data.emoteSetID, [data](TwitchChannel &chan) {
chan.updateSeventvEmote(data);
});
});
postToThread(
[this, data] {
this->forEachSeventvEmoteSet(
data.emoteSetID, [data](TwitchChannel &chan) {
chan.updateSeventvEmote(data);
});
},
this);
});
this->signalHolder.managedConnect(
seventvEventAPI->signals_.emoteRemoved, [this](const auto &data) {
postToThread([this, data] {
this->forEachSeventvEmoteSet(
data.emoteSetID, [data](TwitchChannel &chan) {
chan.removeSeventvEmote(data);
});
});
postToThread(
[this, data] {
this->forEachSeventvEmoteSet(
data.emoteSetID, [data](TwitchChannel &chan) {
chan.removeSeventvEmote(data);
});
},
this);
});
this->signalHolder.managedConnect(
seventvEventAPI->signals_.userUpdated, [this](const auto &data) {
+2
View File
@@ -94,6 +94,8 @@ public:
void initialize();
void aboutToQuit();
void forEachChannelAndSpecialChannels(
std::function<void(ChannelPtr)> func) override;
@@ -75,6 +75,11 @@ void Connection::onNotification(const lib::messages::Metadata &metadata,
void Connection::onClose(std::unique_ptr<lib::Listener> self,
const std::optional<std::string> &reconnectURL)
{
if (isAppAboutToQuit())
{
return;
}
auto *app = tryGetApp();
if (!app)
{
+19 -2
View File
@@ -104,7 +104,10 @@ Controller::~Controller()
connection->close();
}
this->subscriptions.clear();
{
std::lock_guard lock(this->subscriptionsMutex);
this->subscriptions.clear();
}
this->work.reset();
@@ -341,7 +344,7 @@ void Controller::subscribe(const SubscriptionRequest &request, bool isRetry)
qCDebug(LOG) << "Make helix request for" << request;
getHelix()->createEventSubSubscription(
request, listener->getSessionID(),
[this, request, connection,
[this, request,
weakConnection{std::weak_ptr<lib::Session>(connection)}](
const auto &res) {
qCDebug(LOG) << "Subscription success" << request;
@@ -507,6 +510,12 @@ void Controller::registerConnection(std::weak_ptr<lib::Session> &&connection)
void Controller::retrySubscription(const SubscriptionRequest &request)
{
if (isAppAboutToQuit())
{
qCDebug(LOG) << "retrySubscription, but app is quitting" << request;
return;
}
std::lock_guard lock(this->subscriptionsMutex);
auto &subscription = this->subscriptions[request];
@@ -536,6 +545,14 @@ void Controller::retrySubscription(const SubscriptionRequest &request)
std::make_unique<boost::asio::system_timer>(this->ioContext);
retryTimer->expires_after(subscription.backoff.next() + jitter);
retryTimer->async_wait([this, request](const auto &ec) {
if (isAppAboutToQuit())
{
qCDebug(LOG)
<< "Retry was going to fire, but app is quitting so we won't."
<< request;
return;
}
if (!ec)
{
qCDebug(LOG) << "Firing retry" << request;