feat: use Sentry for crash reporting

This commit is contained in:
ZavaruKitsu 2024-01-28 22:44:48 +03:00
parent 1e34bc6b30
commit 58e38c487a
4 changed files with 124 additions and 144 deletions

View file

@ -6,6 +6,11 @@
// Copyright @Radolyn, 2023
#include "ayu_settings.h"
#include "ayu/ui/ayu_assets.h"
#include "lang_auto.h"
#include "core/application.h"
#include "rpl/lifetime.h"
#include "rpl/producer.h"
#include "rpl/variable.h"
@ -181,6 +186,81 @@ void save()
postinitialize();
}
AyuGramSettings::AyuGramSettings()
{
// ~ Ghost essentials
sendReadMessages = true;
sendReadStories = true;
sendOnlinePackets = true;
sendUploadProgress = true;
sendOfflinePacketAfterOnline = false;
markReadAfterSend = true;
markReadAfterReaction = true;
markReadAfterPoll = true;
useScheduledMessages = false;
// ~ Message edits & deletion history
saveDeletedMessages = false;
saveMessagesHistory = true;
// ~ QoL toggles
disableAds = true;
disableStories = false;
collapseSimilarChannels = true;
hideSimilarChannels = false;
uploadSpeedBoost = false;
disableNotificationsDelay = false;
localPremium = false;
copyUsernameAsLink = true;
// ~ Customization
appIcon = AyuAssets::DEFAULT_ICON;
simpleQuotesAndReplies = true;
deletedMark = "🧹";
editedMark = Core::IsAppLaunched() ? tr::lng_edited(tr::now) : QString("edited");
recentStickersCount = 50;
// context menu items
// 0 - hide
// 1 - show normally
// 2 - show with SHIFT or CTRL pressed
showReactionsPanelInContextMenu = 1;
showViewsPanelInContextMenu = 1;
showHideMessageInContextMenu = 0;
showUserMessagesInContextMenu = 2;
showMessageDetailsInContextMenu = 2;
showLReadToggleInDrawer = true;
showSReadToggleInDrawer = true;
showGhostToggleInDrawer = true;
showStreamerToggleInDrawer = false;
showGhostToggleInTray = true;
showStreamerToggleInTray = false;
mainFont = "";
monoFont = "";
hideNotificationCounters = false;
hideAllChatsFolder = false;
/*
* showPeerId = 0 means no ID shown
* showPeerId = 1 means ID shown as for Telegram API devs
* showPeerId = 2 means ID shown as for Bot API devs (-100)
*/
showPeerId = 2;
showMessageSeconds = false;
// ~ Confirmations
stickerConfirmation = false;
gifConfirmation = false;
voiceConfirmation = false;
}
void AyuGramSettings::set_sendReadMessages(bool val)
{
sendReadMessages = val;

View file

@ -6,10 +6,8 @@
// Copyright @Radolyn, 2023
#pragma once
#include "lang_auto.h"
#include "ayu/libs/json.hpp"
#include "ayu/libs/json_ext.hpp"
#include "ayu/ui/ayu_assets.h"
#include "rpl/producer.h"
namespace AyuSettings
@ -18,80 +16,7 @@ namespace AyuSettings
class AyuGramSettings
{
public:
AyuGramSettings()
{
// ~ Ghost essentials
sendReadMessages = true;
sendReadStories = true;
sendOnlinePackets = true;
sendUploadProgress = true;
sendOfflinePacketAfterOnline = false;
markReadAfterSend = true;
markReadAfterReaction = true;
markReadAfterPoll = true;
useScheduledMessages = false;
// ~ Message edits & deletion history
saveDeletedMessages = false;
saveMessagesHistory = true;
// ~ QoL toggles
disableAds = true;
disableStories = false;
collapseSimilarChannels = true;
hideSimilarChannels = false;
uploadSpeedBoost = false;
disableNotificationsDelay = false;
localPremium = false;
copyUsernameAsLink = true;
// ~ Customization
appIcon = AyuAssets::DEFAULT_ICON;
simpleQuotesAndReplies = true;
deletedMark = "🧹";
editedMark = tr::lng_edited(tr::now);
recentStickersCount = 50;
// context menu items
// 0 - hide
// 1 - show normally
// 2 - show with SHIFT or CTRL pressed
showReactionsPanelInContextMenu = 1;
showViewsPanelInContextMenu = 1;
showHideMessageInContextMenu = 0;
showUserMessagesInContextMenu = 2;
showMessageDetailsInContextMenu = 2;
showLReadToggleInDrawer = true;
showSReadToggleInDrawer = true;
showGhostToggleInDrawer = true;
showStreamerToggleInDrawer = false;
showGhostToggleInTray = true;
showStreamerToggleInTray = false;
mainFont = "";
monoFont = "";
hideNotificationCounters = false;
hideAllChatsFolder = false;
/*
* showPeerId = 0 means no ID shown
* showPeerId = 1 means ID shown as for Telegram API devs
* showPeerId = 2 means ID shown as for Bot API devs (-100)
*/
showPeerId = 2;
showMessageSeconds = false;
// ~ Confirmations
stickerConfirmation = false;
gifConfirmation = false;
voiceConfirmation = false;
}
AyuGramSettings();
bool sendReadMessages;
bool sendReadStories;

View file

@ -79,9 +79,9 @@ bool TryHandleSpotify(const QString& url)
// https://www.iana.org/assignments/uri-schemes/prov/spotify
using namespace qthelp;
auto matchOptions = RegExOption::CaseInsensitive;
const auto matchOptions = RegExOption::CaseInsensitive;
// https://regex101.com/r/l4Ogzf/2
auto match = regex_match(
const auto match = regex_match(
u"^(https?:\\/\\/)?([a-zA-Z0-9_]+)\\.spotify\\.com\\/(?<type>track|album|artist|user|playlist)\\/(?<identifier>[a-zA-Z0-9_\\/]+?)((\\?si=.+)?)$"_q,
url,
matchOptions);

View file

@ -276,7 +276,11 @@ LastCrashedWindow::LastCrashedWindow(
, _launch(std::move(launch)) {
excludeReportUsername();
if (!cInstallBetaVersion() && !cAlphaVersion()) {
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
if (false) {
#else
if (true) {
#endif
// Currently accept crash reports only from testers.
_sendingState = SendingNoReport;
} else if (Core::OpenGLLastCheckFailed()) {
@ -439,7 +443,7 @@ LastCrashedWindow::LastCrashedWindow(
});
_saveReport.setText(u"SAVE TO FILE"_q);
connect(&_saveReport, &QPushButton::clicked, [=] { saveReport(); });
_getApp.setText(u"GET THE LATEST OFFICIAL VERSION OF AyuGram DESKTOP"_q);
_getApp.setText(u"GET THE LATEST OFFICIAL VERSION OF AYUGRAM DESKTOP"_q);
connect(&_getApp, &QPushButton::clicked, [=] {
QDesktopServices::openUrl(u"https://github.com/AyuGram/AyuGramDesktop"_q);
});
@ -533,21 +537,7 @@ void LastCrashedWindow::sendReport() {
_sendReply = nullptr;
}
QString apiid = getReportField(qstr("apiid"), qstr("ApiId:")), version = getReportField(qstr("version"), qstr("Version:"));
_checkReply = _sendManager.get(QNetworkRequest(u"https://tdesktop.com/crash.php?act=query_report&apiid=%1&version=%2&dmp=%3&platform=%4"_q.arg(
apiid,
version,
QString::number(minidumpFileName().isEmpty() ? 0 : 1),
CrashReports::PlatformString())));
connect(
_checkReply,
&QNetworkReply::errorOccurred,
[=](QNetworkReply::NetworkError code) { sendingError(code); });
connect(
_checkReply,
&QNetworkReply::finished,
[=] { checkingFinished(); });
checkingFinished();
_pleaseSendReport.setText(u"Sending crash report..."_q);
_sendingState = SendingProgress;
@ -565,41 +555,39 @@ QString LastCrashedWindow::minidumpFileName() {
}
void LastCrashedWindow::checkingFinished() {
if (!_checkReply || _sendReply) return;
QByteArray result = _checkReply->readAll().trimmed();
_checkReply->deleteLater();
_checkReply = nullptr;
LOG(("Crash report check for sending done, result: %1").arg(QString::fromUtf8(result)));
if (result == "Old") {
_pleaseSendReport.setText(u"This report is about some old version of Telegram Desktop."_q);
_sendingState = SendingTooOld;
updateControls();
return;
} else if (result == "Unofficial") {
_pleaseSendReport.setText(u"You use some custom version of Telegram Desktop."_q);
_sendingState = SendingUnofficial;
updateControls();
return;
} else if (result != "Report") {
_pleaseSendReport.setText(u"Thank you for your report!"_q);
_sendingState = SendingDone;
updateControls();
CrashReports::Restart();
return;
}
if (_sendReply) return;
auto multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
addReportFieldPart(qstr("platform"), qstr("Platform:"), multipart);
addReportFieldPart(qstr("version"), qstr("Version:"), multipart);
{
QString version = getReportField(qstr("version"), qstr("Version:"));
if (!version.isEmpty()) {
const auto sentryVersion = QString("ayugram-desktop@%1").arg(version);
QHttpPart reportPart;
reportPart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant(u"form-data; name=\"%1\""_q.arg("sentry[release]")));
reportPart.setBody(sentryVersion.toUtf8());
multipart->append(reportPart);
}
}
{
QString dumpFile = minidumpFileName();
if (!dumpFile.isEmpty()) {
const auto dumpId = dumpFile.replace(".dmp", "");
QHttpPart reportPart;
reportPart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant(u"form-data; name=\"%1\""_q.arg("sentry[tags][dump-id]")));
reportPart.setBody(dumpId.toUtf8());
multipart->append(reportPart);
}
}
QHttpPart reportPart;
reportPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
reportPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"report\"; filename=\"report.telegramcrash\""));
reportPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"report\"; filename=\"report.txt\""));
reportPart.setBody(getCrashReportRaw());
multipart->append(reportPart);
@ -610,30 +598,17 @@ void LastCrashedWindow::checkingFinished() {
QByteArray minidump = file.readAll();
file.close();
QString zipName = QString(dmpName).replace(qstr(".dmp"), qstr(".zip"));
QHttpPart dumpPart;
dumpPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
dumpPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(u"form-data; name=\"upload_file_minidump\"; filename=\"%1\""_q.arg(dmpName)));
dumpPart.setBody(minidump);
multipart->append(dumpPart);
zlib::FileToWrite minidumpZip;
zip_fileinfo zfi = { { 0, 0, 0, 0, 0, 0 }, 0, 0, 0 };
QByteArray dmpNameUtf = dmpName.toUtf8();
minidumpZip.openNewFile(dmpNameUtf.constData(), &zfi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
minidumpZip.writeInFile(minidump.constData(), minidump.size());
minidumpZip.closeFile();
minidumpZip.close();
if (minidumpZip.error() == ZIP_OK) {
QHttpPart dumpPart;
dumpPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
dumpPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(u"form-data; name=\"dump\"; filename=\"%1\""_q.arg(zipName)));
dumpPart.setBody(minidumpZip.result());
multipart->append(dumpPart);
_minidump.setText(u"+ %1 (%2 KB)"_q.arg(zipName).arg(minidumpZip.result().size() / 1024));
}
_minidump.setText(u"+ %1 (%2 KB)"_q.arg(dmpName).arg(minidump.size() / 1024));
}
}
_sendReply = _sendManager.post(QNetworkRequest(u"https://tdesktop.com/crash.php?act=report"_q), multipart);
_sendReply = _sendManager.post(QNetworkRequest(u"https://sentry.radolyn.com/api/2/minidump/?sentry_key=cad638b2ec4a692e57c3dcc4af1508bf"_q), multipart);
multipart->setParent(_sendReply);
connect(