Skip to content

✨ add beforeSend event filtering and scrubbing#177

Draft
rgaignault wants to merge 2 commits into
mainfrom
roman.gaignault/before-send
Draft

✨ add beforeSend event filtering and scrubbing#177
rgaignault wants to merge 2 commits into
mainfrom
roman.gaignault/before-send

Conversation

@rgaignault

@rgaignault rgaignault commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Motivation

Allow applications to filter and scrub RUM events before they are sent.

Changes

Adds a beforeSend configuration callback for main and renderer RUM events, with documentation, playground controls, and test coverage.

Test instructions

  • yarn test:unit
  • yarn test:e2e
  • yarn --cwd playground test

Checklist

  • Tested locally (playground)
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated related documentation.
  • Agentic code review findings addressed or explicitly dismissed.

@rgaignault

Copy link
Copy Markdown
Contributor Author

@codex review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review — Score: 4.4 / 5

This is a strong, well-scoped feature addition. The shared RumEventMapper is wired at the right boundary—after format hooks assemble main-process and renderer events, but before ServerRumEvent emission—so filtered events skip transport and main-process view counters. The clone-and-allowlist approach mirrors Browser SDK semantics, protects view/crash events, bypasses internal view_update payloads, and is backed by thorough unit, e2e, and playground coverage plus clear customer docs. I would approve.

Why 4.4: Solid architecture, defensive scrubbing (sanitize, type-checked allowlist), fail-open error handling, explicit tests for edge cases (throws, protected events, unknown event types), and documentation that calls out Electron-specific limitations (no raw DOM/XHR context, renderer counter staleness).

Why not 5: A few integrator-facing behaviors are implicit rather than documented (session activity on filtered clicks; only explicit false discards), and deepClone on every mapped event is a latent perf cost for very high-volume apps.


Findings

  • [Minor] Filtered clicks still renew sessionEND_USER_ACTIVITY is emitted before beforeSend, so discarding renderer click events does not suppress session keep-alive/renewal side effects.
  • [Minor] Only explicit false drops eventsundefined and other non-false return values keep the event, which is reasonable but slightly at odds with the boolean type/docs.
  • [Nit] Default mapper in constructorsMainAssembly/RendererPipeline default to new RumEventMapper() without config.beforeSend; only init() passes the shared configured instance.

Architectural flow

sequenceDiagram
    participant Src as Main RawEvent or Renderer IPC
    participant Hooks as Format Hooks
    participant Mapper as RumEventMapper
    participant Out as ServerRumEvent / Transport

    Src->>Hooks: triggerRum(source, eventType)
    Hooks->>Mapper: fully assembled RumEvent
    Mapper->>Mapper: deepClone + beforeSend on clone
    alt explicit false and droppable type
        Mapper-->>Out: discarded (no ServerRumEvent)
    else keep or scrub
        Mapper->>Mapper: copy allowlisted fields + sanitize
        Mapper->>Out: emit ServerRumEvent
    end
Loading

Before: RUM events flowed from assembly straight to transport once hooks enriched them.

After: Both MainAssembly and RendererPipeline share one RumEventMapper configured from init({ beforeSend }). Customers can scrub allowlisted fields or return false to drop events after all Electron context is attached; view, crash, and internal view_update events are protected. Telemetry, profiles, and spans are unchanged.

Open in Web View Automation 

Sent by Cursor Automation: electron-sdk reviews

Comment thread src/assembly/RumEventMapper.ts Outdated
return event;
}

event.context ??= {};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mutates the live event object before cloning (adding {} when context was absent). It is needed so allowlisted context writes round-trip, but it does mean beforeSend is not a pure read on the pre-mapper object. Worth a brief code comment if this trips future maintainers.

Comment thread src/assembly/RumEventMapper.ts
Comment thread src/assembly/MainAssembly.ts Outdated
private eventManager: EventManager,
private hooks: FormatHooks
private hooks: FormatHooks,
private rumEventMapper = new RumEventMapper()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default new RumEventMapper() here (and in RendererPipeline) silently ignores config.beforeSend unless callers pass the shared mapper from init(). Fine for the public path today, but easy to footgun in future internal wiring—consider requiring the mapper parameter or threading config.

Comment thread README.md

Renderer events have already passed through any `beforeSend` configured in the renderer's Browser SDK. The Electron callback runs afterward, once main-process context is added. It can run multiple times for the same view as its metrics change; internal `view_update` payloads are not exposed.

Renderer view counters are computed by the Browser SDK before events reach the main process, so filtering a renderer event here does not retroactively adjust those counters.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already document renderer view-counter staleness. Consider also noting that filtering renderer click actions still emits internal session activity (END_USER_ACTIVITY) so sessions can renew even when the click RUM event is discarded—this is tested in RendererPipeline.spec.ts and may surprise integrators.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 10244b5bd0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config.ts
Comment thread src/assembly/RumEventMapper.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant