Cockatrice 2026-10-19-Development-3.1.2-beta.2
A virtual tabletop for multiplayer card games
Loading...
Searching...
No Matches
CrashReporter Class Reference

Sentry-backed crash-report facade, owned by main(). More...

#include <crash_reporter.h>

Public Member Functions

 CrashReporter ()
 CrashReporter (const CrashReporter &)=delete
CrashReporter & operator= (const CrashReporter &)=delete
 CrashReporter (CrashReporter &&)=delete
CrashReporter & operator= (CrashReporter &&)=delete
 ~CrashReporter ()
void init (const QString &dsn, const QString &release, const QString &databasePath, PersonalSettings::CrashReportingMode consentMode)
bool isReady () const
void shutdown ()
void giveConsent ()
void revokeConsent ()
bool sendReport (const QString &redactedPreview, const QString &userNote=QString())
int attachToPendingCrashEnvelopes (const QString &redactedLogText, const QString &userNoteText)
 Append the redacted log (and optional user note) to every pending native crash envelope in the local database, so the crashed event uploads with dump, stack, log and note together instead of the log arriving as a separate event that has to be correlated by hand. Both storage locations are covered: consent-held envelopes in <database>/cache (Ask mode) and in-flight envelopes dumped into <database>/<run>.run (AlwaysSend mode).
bool beginSession (const QString &dir)
 Claim this process's session lock, reporting a previous unclean exit.
void endSession ()

Static Public Member Functions

static int attachToPendingCrashEnvelopes (const QString &databasePath, const QString &redactedLogText, const QString &userNoteText)
static bool appendAttachmentToEnvelope (const QString &envelopePath, const QString &filename, const QByteArray &payload)
 Append one attachment item to a cached Sentry envelope file.
static QStringList pendingEnvelopePaths (const QString &databasePath)
 Pending crash envelopes in <database>: the consent-held files in <database>/cache and the in-flight files in <database>/<run>.run.
static bool isReportingEnabled (const QString &dsn, PersonalSettings::CrashReportingMode consentMode)
 SDK-independent gating decision, unit-testable in OFF builds.
static bool isDsnWellFormed (const QString &dsn)
 Whether a DSN has the shape the build and the SDK require: <scheme>://<key><host>/<project-id>.
static QString describeDsn (const QString &dsn)
 Human-readable destination of a DSN, e.g. "o0.ingest.sentry.io (project 1234567)".
static QString describeOriginMismatch (const QString &envelopePath, const QString &currentDsn)
 Describe the captured-for DSN of a pending envelope when it points at a different destination than the DSN this session would upload it with; empty when they agree.
static QString sanitizeLogLine (const QString &line)
static QString redactCockatriceUrls (const QString &line)

Private Attributes

bool ready = false
QString sentryDatabasePath
QString sessionLockPath
std::unique_ptr< QLockFile > sessionLock

Detailed Description

Sentry-backed crash-report facade, owned by main().

An empty DSN (or Never consent) skips the SDK entirely, so the mock dialog fallback behaves exactly as before. All SDK calls are guarded so OFF builds compile to no-ops.

Consent gating
init() arms require-user-consent and before_send scrubbing. Stale persisted consent from a previous AlwaysSend run is cleared before init when the mode is not AlwaysSend, and cached crash envelopes are held for the dialog instead of being dropped. giveConsent()/revokeConsent() gate uploads.
Envelope and log helpers
attachToPendingCrashEnvelopes() folds the redacted log and the optional user note into the pending native crash event(s) before consent releases them, so dump, stack, log and note arrive as ONE Sentry event. sendReport() is the fallback for unclean exits that produced no native crash event, capturing a redacted message event with the log preview attached. The log redaction helpers are static and SDK-independent.
Session tracking
beginSession()/endSession() are SDK-independent: a QLockFile per process in the database dir detects unclean exits cross-platform, replacing the legacy Windows-only .dmp scan. The held lock makes the reporter non-copyable and non-movable.

Constructor & Destructor Documentation

◆ CrashReporter() [1/3]

CrashReporter::CrashReporter ( )
default
Here is the caller graph for this function:

◆ CrashReporter() [2/3]

CrashReporter::CrashReporter ( const CrashReporter & )
delete
Here is the call graph for this function:

◆ CrashReporter() [3/3]

CrashReporter::CrashReporter ( CrashReporter && )
delete
Here is the call graph for this function:

◆ ~CrashReporter()

CrashReporter::~CrashReporter ( )
default
Here is the call graph for this function:

Member Function Documentation

◆ appendAttachmentToEnvelope()

bool CrashReporter::appendAttachmentToEnvelope ( const QString & envelopePath,
const QString & filename,
const QByteArray & payload )
static

Append one attachment item to a cached Sentry envelope file.

An envelope is a newline-separated stream of item-header-line + payload pairs. The retry transport replays cached envelopes byte-for-byte (sentry-native 0.17.3 reads them raw and serializes raw envelopes back verbatim), so appending well-formed items associates them with the event already in the file; the first line (event id header) is never touched.

Parameters
filenameASCII-only item filename, embedded verbatim in the header.
Here is the caller graph for this function:

◆ attachToPendingCrashEnvelopes() [1/2]

int CrashReporter::attachToPendingCrashEnvelopes ( const QString & databasePath,
const QString & redactedLogText,
const QString & userNoteText )
static
Here is the call graph for this function:

◆ attachToPendingCrashEnvelopes() [2/2]

int CrashReporter::attachToPendingCrashEnvelopes ( const QString & redactedLogText,
const QString & userNoteText )

Append the redacted log (and optional user note) to every pending native crash envelope in the local database, so the crashed event uploads with dump, stack, log and note together instead of the log arriving as a separate event that has to be correlated by hand. Both storage locations are covered: consent-held envelopes in <database>/cache (Ask mode) and in-flight envelopes dumped into <database>/<run>.run (AlwaysSend mode).

For the AlwaysSend variant run this BEFORE init() (static overload): the startup replay of *.run envelopes happens inside sentry_init. SDK-independent plain-file surgery on the Sentry envelope format, so it stays unit-testable in OFF builds.

Returns
the number of envelopes that received the attachments.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ beginSession()

bool CrashReporter::beginSession ( const QString & dir)

Claim this process's session lock, reporting a previous unclean exit.

Returns
true if a leftover session lock from a dead process (or an unreadable garbage file) was found and cleaned; live concurrent instances are ignored.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ describeDsn()

QString CrashReporter::describeDsn ( const QString & dsn)
static

Human-readable destination of a DSN, e.g. "o0.ingest.sentry.io (project 1234567)".

Safe to log: the public key is never part of the result. Empty for a malformed DSN.

Here is the caller graph for this function:

◆ describeOriginMismatch()

QString CrashReporter::describeOriginMismatch ( const QString & envelopePath,
const QString & currentDsn )
static

Describe the captured-for DSN of a pending envelope when it points at a different destination than the DSN this session would upload it with; empty when they agree.

sentry-native posts every envelope with the DSN held in the transport state of the session doing the sending (envelopes restored from disk are raw and their own "dsn" header is never read), so a cached crash envelope captured for one project can silently be uploaded to another - the exact way a tester's report lands in the wrong place. Compares destinations (host and project id), not raw strings, so a different key for the same project stays quiet.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ endSession()

void CrashReporter::endSession ( )
Here is the caller graph for this function:

◆ giveConsent()

void CrashReporter::giveConsent ( )
Here is the caller graph for this function:

◆ init()

void CrashReporter::init ( const QString & dsn,
const QString & release,
const QString & databasePath,
PersonalSettings::CrashReportingMode consentMode )
Here is the call graph for this function:
Here is the caller graph for this function:

◆ isDsnWellFormed()

bool CrashReporter::isDsnWellFormed ( const QString & dsn)
static

Whether a DSN has the shape the build and the SDK require: <scheme>://<key><host>/<project-id>.

Deliberately the same unanchored pattern cmake/CrashReporting.cmake matches (CMake's MATCHES searches rather than anchoring), so a DSN this build accepted is never rejected here. The SDK refuses to even build a request for a DSN it considers invalid, so an unchecked typo disables uploading with no error anywhere.

Here is the caller graph for this function:

◆ isReady()

bool CrashReporter::isReady ( ) const
nodiscard
Here is the caller graph for this function:

◆ isReportingEnabled()

bool CrashReporter::isReportingEnabled ( const QString & dsn,
PersonalSettings::CrashReportingMode consentMode )
static

SDK-independent gating decision, unit-testable in OFF builds.

Here is the caller graph for this function:

◆ operator=() [1/2]

CrashReporter & CrashReporter::operator= ( const CrashReporter & )
delete
Here is the call graph for this function:

◆ operator=() [2/2]

CrashReporter & CrashReporter::operator= ( CrashReporter && )
delete
Here is the call graph for this function:

◆ pendingEnvelopePaths()

QStringList CrashReporter::pendingEnvelopePaths ( const QString & databasePath)
static

Pending crash envelopes in <database>: the consent-held files in <database>/cache and the in-flight files in <database>/<run>.run.

Matches the cache filename conventions sentry-native accepts (see sentry__parse_cache_filename): bare "<uuid>.envelope" and retry "<ts>-<count>-<uuid>.envelope"; run dirs accept plain "<uuid>.envelope" minus the SDK's own "__sentry-crash.envelope" marker.

Here is the caller graph for this function:

◆ redactCockatriceUrls()

QString CrashReporter::redactCockatriceUrls ( const QString & line)
static
Here is the caller graph for this function:

◆ revokeConsent()

void CrashReporter::revokeConsent ( )
Here is the caller graph for this function:

◆ sanitizeLogLine()

QString CrashReporter::sanitizeLogLine ( const QString & line)
static
Here is the caller graph for this function:

◆ sendReport()

bool CrashReporter::sendReport ( const QString & redactedPreview,
const QString & userNote = QString() )
Here is the caller graph for this function:

◆ shutdown()

void CrashReporter::shutdown ( )
Here is the caller graph for this function:

Member Data Documentation

◆ ready

bool CrashReporter::ready = false
private

◆ sentryDatabasePath

QString CrashReporter::sentryDatabasePath
private

◆ sessionLock

std::unique_ptr<QLockFile> CrashReporter::sessionLock
private

◆ sessionLockPath

QString CrashReporter::sessionLockPath
private

The documentation for this class was generated from the following files: