Skip to content

Guard Observer .observe() calls against broken browser stubs #SUPERLOG - #445

Open
superlog-app[bot] wants to merge 1 commit into
mainfrom
superlog/observe-guard-vivid-hare
Open

Guard Observer .observe() calls against broken browser stubs #SUPERLOG#445
superlog-app[bot] wants to merge 1 commit into
mainfrom
superlog/observe-guard-vivid-hare

Conversation

@superlog-app

@superlog-app superlog-app Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

The landing page at superlog.sh was crashing with "Superlog hit an unexpected error" for visitors using browser environments (headless browsers, aggressive privacy extensions, or fingerprint-protection modes) where IntersectionObserver and ResizeObserver constructors return stub objects that are missing the .observe() method.

Root Cause

Two recently-added landing page components call .observe() without guarding against broken observer instances:

Both errors propagate to the BrowserErrorBoundary wrapping MarketingApp, which replaces the entire page with the error fallback screen. Both issues were observed at the same timestamp (2026-08-01T07:58:38) from a single browser session on the latest deployment.

Remediation

Wrapped the .observe() calls in try/catch blocks in both components:

  • FluidSignalField: if observing fails, the WebGL animation still runs — it just won't auto-resize or pause when scrolled out of view.
  • AcceptanceStat: if observing fails, resets the count to the final value (90) so the stat still shows correctly without the count-up animation.

The .disconnect() cleanup calls are unaffected (they stay outside the try-catch and remain safe to call on any observer instance).

Related incident: vivid-hare (666da96c-10fa-4683-8536-e743e1de2a13)


Was this PR helpful? Leave feedback — goes straight to the Superlog team.


Summary by cubic

Guarded .observe() calls on IntersectionObserver and ResizeObserver to prevent landing page crashes when browsers return broken stub instances. Users with headless or privacy-hardened setups now see the page; animations degrade gracefully instead of throwing.

  • Bug Fixes
    • FluidSignalField: wrap .observe() in try/catch; animation continues without resize/visibility tracking.
    • AcceptanceStat: wrap .observe() in try/catch; fall back to the final count when observing fails.

Written for commit 909ca23. Summary will update on new commits.

Review in cubic

Delivery-Id: 3cf741aa53f16db54b0de632db02d442514ba66521319713654d75a79553e5d7
Delivery-Base: main

@superlog-app superlog-app Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Observability review

  • 3 warnings

try {
resizeObserver.observe(targetCanvas);
intersectionObserver.observe(targetCanvas);
} catch {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

logs · warning — Log the caught observer error in FluidSignalField

Add a structured error log inside the catch block (including the caught exception) so operators can detect and scope broken-stub environments in production; without it the failure is completely invisible and the incident recurrence rate cannot be measured.

Suggested change
} catch {
} catch (err) {
// Resize and intersection tracking unavailable; proceed without them.
logger.error("observer.observe failed — resize/visibility tracking disabled", { error: err });
}

Useful? React with 👍 / 👎.

Comment thread apps/web/src/Landing.tsx
try {
observer.observe(node);
} catch {
setCount(ACCEPTANCE_RATE);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

logs · warning — Log the caught observer error in AcceptanceStat

Add a structured error log inside the catch block (including the caught exception) so operators can correlate broken-stub occurrences with the vivid-hare incident and detect any new browser environments triggering the same fallback path.

Suggested change
setCount(ACCEPTANCE_RATE);
} catch (err) {
logger.error("IntersectionObserver.observe failed — count-up animation skipped", { error: err });
setCount(ACCEPTANCE_RATE);
return;
}

Useful? React with 👍 / 👎.

try {
resizeObserver.observe(targetCanvas);
intersectionObserver.observe(targetCanvas);
} catch {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

metrics · warning — Increment a counter when observer stubs are broken

Record a low-cardinality counter (e.g. browser_observer_stub_total with dimension component) in both catch blocks so the rate of affected sessions can be tracked over deployments and alerting thresholds can be set without log-mining.

Useful? React with 👍 / 👎.

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