breadcrumb static method
Records a breadcrumb — a trail event attached to the next captured error.
Gated at emit time by AppConfigBase.breadcrumbLevel (independent of
the console logLevel — BEH-3/BEH-4): a breadcrumb whose level is below
the threshold is dropped. The breadcrumb's own level comes from the
optional level param; when omitted it defaults to LogLevel.info
(ERH-031). Gating uses LogLevel only — never a backend level type; the
LogLevel→SentryLevel translation is Sentry-side (the reporter), not here
(ERH-026).
The message + every value in data are redacted (fail-closed — ERH-005,
ERH-017, ERH-047) before being forwarded. When no reporter is attached
the (gated, redacted) breadcrumb is buffered into the bounded
_earlyBreadcrumbBuffer (ERH-022/ERH-032) so the pre-attach trail is not
lost; the flush-on-attach (breadcrumbs-then-errors) is wired where the
reporter attaches.
Never throws into the caller — breadcrumbs are diagnostic and must not perturb the code they trace.
Implementation
static void breadcrumb(
String message, {
String? category,
Map<String, dynamic>? data,
LogLevel level = LogLevel.info,
}) {
try {
if (!_shouldBreadcrumb(level)) {
return;
}
final redacted = _redactSensitiveData(message, data);
final reporter = _customErrorReporter;
if (reporter != null) {
reporter.addBreadcrumb(
redacted.message,
category: category,
data: redacted.data,
);
} else {
// No reporter attached yet — buffer so the pre-attach trail survives
// (flushed on attach, breadcrumbs-then-errors). Already redacted, so the
// flush must NOT re-redact (ERH-032).
_bufferEarlyBreadcrumb(BufferedBreadcrumb(
redacted.message,
category,
redacted.data,
));
}
} catch (_) {
// Diagnostics must never break the traced code path.
}
}