Conversation
MapleBrowser.sendFeedback({ message, email?, name?, attributes? }) sends
a maple.user_feedback OTel log event: session.id, user.email / user.name
(semconv; the email is dropped when privacy.captureUserEmail is false),
maple.feedback.has_replay and, when the user hit an error earlier in the
page, maple.feedback.error_trace_id. The event is linked to that error's
span, so it shows on the error's trace.
Feedback also keeps a buffered replay, the same way an error does: a user
reporting a problem is as good a signal. Headless for now; a drop-in
widget can come as its own entry so it never touches the eager bundle.
Eager budget 43 -> 43.5 kB, first-party 17.5 -> 18 kB.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Maple reviewConfidence 2/5 · risky as written Adds
FindingsWarning · F1 ·
|
| Change | Kind | Observable | Evidence |
|---|---|---|---|
sendFeedback OTel log event |
log | yes | Emits through emitLog (packages/browser/src/feedback.ts:54-67), which the deferred OTLP logs exporter sinks |
| buffered replay kept on feedback | background | no | keepReplay() triggers the existing replay handle; nothing records which signal triggered it |
Copy all findings (2)
Findings from an automated review of commit 338c1b5e70addb092fb76b15fdac044d827fd10f. Verify each one against the current code before changing anything, fix only those that still apply, and keep each fix to the lines it names.
---
F1 · Warning · correctness · packages/browser/src/feedback.ts:53
`maple.feedback.has_replay` is false on the buffered replay feedback keeps
`recorded` is read from `getSession().replaySampled` before `keepReplay()` runs, so on the buffered-replay path (`replay.onErrorSampleRate`, no earlier error on the page) it is always `false`: the session is buffered precisely because `claimReplaySample` rolled `replaySampled: false` (`packages/browser-session/src/session/session.ts:622-647`). The event therefore reports `maple.feedback.has_replay = false` for the very feedback whose `keepReplay()` uploads the buffered minute — `trigger()` writes `replaySampled: true` (`session.ts:650-654`) only after the attribute was already computed. Call `keepReplay()` before reading the record so the attribute matches what was actually uploaded.
---
F2 · Note · correctness · packages/browser/src/init.ts:249
`lastError` survives `shutdown()` and links feedback to a dead trace
`shutdown()` resets the other feedback state (`captureUserEmail`, `keepReplay`) but not the module-level `lastError`, which only `resetFeedbackForTests` clears (`packages/browser/src/feedback.ts:39-43`). A page that calls `init()` again after `shutdown()` — or a fresh session after a consent revoke/re-grant — sends its first feedback linked to a span from the previous SDK lifecycle, so the event lands on an unrelated trace and carries a stale `maple.feedback.error_trace_id`.
Suggested fix: Have `configureFeedback` (or a small `clearFeedback()` beside it) drop `lastError` too, and call the same reset here as `resetFeedbackForTests`.
338c1b5 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple to ask about one.
maple.feedback.has_replay was read before keepReplay() ran, so on the buffered-replay path it was always false for the very feedback that kept the replay. keepReplay() now runs first; the trigger marks the session recorded synchronously.
Maple reviewConfidence 4/5 · likely safe to merge Adds headless
Still open from earlier reviews
What was checked
Observability coverage: 1 of 1 changes observable
|
lastError survived shutdown(), so feedback after a re-init linked to a trace from the previous lifecycle. configureFeedback, run by init() and shutdown(), now clears it.
Maple reviewConfidence 5/5 · safe to merge Adds
Fixed since the last review
What was checked
Observability coverage: 1 of 1 changes observable
|
Part 9 of the browser SDK stack. Based on the error-triggered replay PR.
What changes
MapleBrowser.sendFeedback({ message, email?, name?, attributes? })sends amaple.user_feedbackOTel log event with:session.id;user.email/user.name(semconv; the email is dropped whenprivacy.captureUserEmailis false);maple.feedback.has_replay;maple.feedback.error_trace_id, when the user hit an error earlier on the page.falsewhen nothing was sent (empty message, no consent).Headless for now (bring your own form). A drop-in widget can come later as its own entry so it never touches the eager bundle. Reading feedback in the product (a list, or on the session detail page) is backend/UI follow-up; until then it's queryable as logs.
Eager budget 43 → 43.5 kB, first-party 17.5 → 18 kB.
Testing
Browser tests through
init(): the event carries the message, user fields, attributes, session and error link;captureUserEmail: falsedrops the email; an empty message sends nothing.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.