Skip to content

fix: resolve top Sentry issues (PPM-4, PPM-A, PPM-8)#136

Merged
mostafazh merged 2 commits into
TechForPalestine:mainfrom
mostafazh:fix/sentry-top-issues
Jul 18, 2026
Merged

fix: resolve top Sentry issues (PPM-4, PPM-A, PPM-8)#136
mostafazh merged 2 commits into
TechForPalestine:mainfrom
mostafazh:fix/sentry-top-issues

Conversation

@mostafazh

Copy link
Copy Markdown
Collaborator

Summary

Fixes the top Sentry issues in the ppm project (Tech For Palestine), taken from the highest-volume unresolved errors. These three issues account for ~70% of all captured error events (55 of 78).

Each fix is in its own commit.

Fixes

1. PPM-4 — React removeChild crash (46 events, the Top 1 issue)

NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

The classic React + browser-translation conflict. Google Translate / mobile-Chrome & in-app-browser auto-translate replace the text nodes React is tracking; when React later removes or reinserts one, its parent has changed and the raw DOM call throws, crashing the whole app. Affected events are overwhelmingly non-English locales (Tunisia, Belgium, Germany, India) where auto-translate triggers.

Fix: a small client-only DomSafety patch (mounted from the root layout) that makes Node.prototype.removeChild / insertBefore no-op only in the case that would otherwise throw. Well-formed DOM operations are untouched. See facebook/react#11538.

2. PPM-A + PPM-8 — unhandled fetch rejection (6 + 3 events)

TypeError: Load failed (Safari) / TypeError: Failed to fetch (Chrome), both via onunhandledrejection.

The /api/gaza-status fetch on the landing page had no error handling (fetch().then(res => res.json()).then(...)). A failed request (offline, ad-blocker, in-app browser, flaky network) became an unhandled promise rejection. Confirmed via matching app frame in page.js — it's the only bare fetch without a .catch().

Fix: add a .catch() and guard against a non-ok response. The banner it feeds is non-essential, so failures now degrade silently.

Out of scope (deliberately not fixed here)

  • PPM-5 (Maximum call stack size exceeded) — stack is undefined:31:70 with no app frames; not confidently attributable to our code (likely an extension/injected script).
  • PPM-6 (NotFoundError: The object can not be found here.) — ambiguous DOM error; may be mitigated by the PPM-4 patch but not verified.
  • PPM-9 / PPM-7 / PPM-B (window.webkit.messageHandlers, Java object is gone) — in-app-browser (WKWebView / Android WebView) injected-script noise, not our code. Better addressed via Sentry ignoreErrors filtering than a code change.

Verification

  • npm run lint — 0 errors (1 pre-existing <img> warning, unrelated)
  • tsc --noEmit — clean
  • npm run build — compiles, / prerenders (confirms the SSR Node guard)
  • npm test — 3/3 pass

🤖 Generated with Claude Code

claude and others added 2 commits July 18, 2026 03:33
The /api/gaza-status request in the landing page had no error handling:
`fetch().then(res => res.json()).then(...)`. When the request fails
(offline, ad-blocker, in-app browser, flaky network) the rejection is
unhandled and reported to Sentry as "TypeError: Failed to fetch" (Chrome)
or "TypeError: Load failed" (Safari), both via
onunhandledrejection. The banner it feeds is non-essential, so failures
should degrade silently.

Add a `.catch()` and guard against a non-ok response so a failed request
just logs and leaves the banner hidden instead of crashing out as an
unhandled promise rejection.

Fixes PPM-A
Fixes PPM-8

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbAFxseaTp5zr72vtKuBUo
Mobile users hit a hard crash reported to Sentry as "NotFoundError:
Failed to execute 'removeChild' on 'Node': The node to be removed is not
a child of this node" (PPM-4, the highest-volume issue). The stacktrace
is React's commit phase (removeChild/insertBefore) recursing through the
vendor chunk.

This is the well-known React + browser-translation conflict: Google
Translate / mobile-Chrome & in-app-browser auto-translate swap out the
text nodes React is tracking, so when React later removes or reinserts
one of them its parent has changed and the raw DOM call throws, taking
down the whole app. The affected events are overwhelmingly non-English
locales (Tunisia, Belgium, Germany, India) where auto-translate kicks in.

Add a small client-only DomSafety patch, mounted from the root layout,
that makes Node.prototype.removeChild / insertBefore no-op in exactly the
case that would otherwise throw (node no longer under the expected
parent). It only intercepts the throwing case, so valid DOM operations
are unaffected. See react/react#11538.

Fixes PPM-4

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbAFxseaTp5zr72vtKuBUo
@mostafazh
mostafazh merged commit bd99b20 into TechForPalestine:main Jul 18, 2026
3 checks passed
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.

2 participants