Repository navigation
fix(core): Avoid parse-time SyntaxError on Safari <16.4 in postgresjs - #20498
Conversation
Closes #20433 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR prevents Safari <16.4 from throwing a parse-time SyntaxError when browser bundles include @sentry/core’s Postgres.js integration by replacing a regex literal containing negative lookbehind with a RegExp constructor (so compilation is deferred to runtime).
Changes:
- Replace the negative-lookbehind regex literal in
_sanitizeSqlQuerywithnew RegExp(...)to avoid Safari parse-time failure. - Add inline rationale explaining the Safari parse-time issue and why runtime construction is used.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Cache the regex in a module-scope let and build it on first call. Evaluating it at module scope would still crash Safari <16.4 at import time. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Matches the style used elsewhere in the repo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e25324c. Configure here.
size-limit report 📦
|
s1gr1d
left a comment
There was a problem hiding this comment.
Like in the Cursor comment already noted: would be nice if there are tests for that.
| // on import and crash Safari <16.4 browser bundles that reach this file via | ||
| // the core barrel. Building it on first call keeps the cost off the import path. | ||
| if (!integerLiteralRE) { | ||
| integerLiteralRE = new RegExp('(?<!\\$)-?\\b\\d+\\b', 'g'); |
There was a problem hiding this comment.
is it even important to have this in module scope? can we not just define this in function scope here?
There was a problem hiding this comment.
just a perf thingy, its the same regex each time so I thought to cache it.
@s1gr1d We already have tests for that regex and that it works, what we don't have tests for is if it crashes on Safari <16 if not tree-shaken properly. which I think we cannot test for. These are the current tests we have: |
… macOS 12 (#2902) Outline Client 1.22.0 shows a blank white screen on iOS/iPadOS 15 and on macOS Monterey. The web bundle contains a RegExp literal with a lookbehind assertion, `(?<!\$)`, from @sentry/core's PostgreSQL query sanitizer (a server-only integration that is bundled anyway). JavaScriptCore before WebKit 16.4 rejects lookbehind at parse time, so the whole bundle fails to load before any UI code runs. The regex came with the Sentry upgrade to 10.47.0 in #2739; upstream added it in @sentry/core 10.41.0 and fixed it in 10.51.0 by building the regex with `new RegExp(...)` (getsentry/sentry-javascript#20498). Babel cannot lower lookbehind, so the browserslist targets did not protect us. Move to the latest 10.x line, pinned to one version across the workspaces: @sentry/browser and @sentry/core 10.75.0, @sentry/electron 7.20.2. The release-mode Cordova and Capacitor bundles now contain no lookbehind regex literal. Fixes #2899. Fixes #2900. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>

Bandaid fix for #20433. Constructs the negative-lookbehind regex via
new RegExp(...)instead of a regex literal, so it is evaluated at runtime rather than at parse time.Safari <16.4 does not support lookbehind assertions as a literal, this causes a parse-time
SyntaxErrorthat kills the entire script.As a constructor call with
new RegExp, parsing succeeds;. Correctness in Safari doesn't matter here, we just don't want the file to fail to parse and it would never execute anyways.The deeper issue is that server-only code from
@sentry/core(postgresjs, express, trpc, mcp-server, the AI instrumentations, etc.) can end up in browser bundles because it seems like some bundlers can't tree-shake it out of the core barrel. We should be more disciplined about what the main@sentry/coreentry re-exports so apps stop shipping server code that never executes.I managed to reproduce this setup in a webpack with CJS app and noticed it didn't tree-shake the postgres integration. Vite seems to do it correctly.
Bringing this up next week, but we should not rely on tree-shaking to eliminate code-paths.