Uh oh!
There was an error while loading. Please reload this page.
fix(local): raisely local hangs on every request and drops page overrides - #86
Open
k-r-a-s-s wants to merge 1 commit into
Open
fix(local): raisely local hangs on every request and drops page overrides#86k-r-a-s-s wants to merge 1 commit into
raisely local hangs on every request and drops page overrides#86k-r-a-s-s wants to merge 1 commit into
Conversation
…rrides
Two independent bugs make `raisely local` unusable in 2.1.0.
1. Every proxied request hangs.
The proxy response handler is registered as `onProxyRes`, which is the
http-proxy-middleware **v2** option name. package.json pins v3.0.5, where
handlers live under `on: { proxyRes }`. v3 ignores the unknown top-level
option but still honours `selfHandleResponse: true`, so the response is
handed to a handler that was never registered, nothing writes to `res`, and
the request hangs until the client times out.
This affects every URL, not just pages -- `/robots.txt` hangs too. Only
`/reload` still answers, because it is a local Express route that never
reaches the proxy.
2. Local page overrides silently never apply.
The generated override payload is passed to `String.prototype.replace` as a
REPLACEMENT STRING:
output.replace(afterCampaignBootstrap, `$1${pageOverride}$2`)
The payload embeds page copy verbatim, so `$1`..`$9`, `$&`, `` $` ``, `$'`
and `$$` in that copy are interpreted as replacement patterns. A campaign
page containing "surviving on less than $2 a day" expands `$2` to capture
group 2 -- the matched `<script>if (window.campaign) {` text -- splicing it
into the middle of a JSON string inside the injected script. The script no
longer parses, so it never runs and `window.pageSchemas` keeps the server's
compiled templates.
The failure is campaign-wide rather than page-scoped, because every page's
compiled template ships in that one script: a single page containing a
dollar amount disables local page editing for the whole campaign. It is also
silent -- the only signal is a console SyntaxError on an unrelated-looking
line. Currency in page copy is not an edge case on a fundraising platform.
Changes:
- Extract `createCampaignProxy()` and register the handler under
`on: { proxyRes }`.
- Extract `injectPageOverride()` and insert the payload with replacer
FUNCTIONS, where `$` has no special meaning. Same fix applied to the two
fallback injection branches and the `<head>` API-redirect injection, which
had the same latent hazard.
- Add tests/local-proxy.test.js. Both are true regression tests: restoring
either bug fails them (the proxy test with an explicit message rather than an
opaque timeout).
Formatting follows the surrounding file. Upstream does not currently pass
`prettier --check` (9 files), so no repo-wide reformat is included here.
Verified against a live campaign: proxy returns in ~0.3s, the override map
carries all 72 local pages, and an un-deployed local edit to a page JSON
renders at localhost:8015.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
raisely localis unusable in 2.1.0. Two independent bugs, both insrc/local.js.1. Every proxied request hangs
The proxy response handler is registered as
onProxyRes— the http-proxy-middleware v2 option name.package.jsonpins 3.0.5, where handlers live underon: { proxyRes }. v3 ignores the unknown top-level option but still honoursselfHandleResponse: true, so the response is handed to a handler that was never registered, nothing writes tores, and the request hangs until the client gives up.This affects every URL, not just pages —
/robots.txthangs too. Only/reloadstill answers, because it's a local Express route that never reaches the proxy.Isolated with a 3-case matrix against the same upstream:
onProxyRes+selfHandleResponse: true— currenton: { proxyRes }+selfHandleResponse: trueonProxyRes, noselfHandleResponsefollowRedirectsand the<path>.raisely.com→<path>.raiselysite.com302 both look suspicious and are both red herrings — the hang reproduces against a direct-200 target too.2. Local page overrides silently never apply
The generated override payload is passed to
String.prototype.replaceas a replacement string:The payload embeds page copy verbatim, so
$1–$9,$&,$`,$'and$$appearing in that copy are interpreted as replacement patterns. A page on our campaign contains the copy "surviving on less than$2a day". That$2expands to capture group 2 — the matched<script>if (window.campaign) {text — which gets spliced into the middle of a JSON string inside the injected script. The script no longer parses, so it never runs andwindow.pageSchemaskeeps the server's compiled templates.Two things make this hard to spot:
SyntaxError: Invalid or unexpected tokenon an unrelated-looking line.Currency in page copy isn't an edge case on a fundraising platform.
Changes
createCampaignProxy(); register the handler underon: { proxyRes }.injectPageOverride(); insert the payload with replacer functions, where$has no special meaning. Applied the same fix to the two fallback injection branches (<!-- _footer_integrations_ -->and</body>) and the<head>API-redirect injection — same latent hazard.tests/local-proxy.test.js.Both new tests are true regression tests — I re-introduced each bug and confirmed they fail:
$-token cases, including a full-path case that runs a realbuildPageOverrideScriptoutput throughvm.Scriptto assert it parsesVerification
npm test: 116 passed (13 files).Against a live campaign with the branch installed:
/robots.txt200,/en/terms200)localhost:8015, and thepageSchemasentry is patched at DOMContentLoadedNote on formatting
I matched the surrounding file style rather than running Prettier. Upstream
masterdoesn't currently passprettier --check(9 files warn, no config committed), so a repo-wide reformat would have buried the fix. Happy to add one if you'd prefer.Unrelated to (and independent of) #85 — different file, branches off
mastercleanly.Note
Medium Risk
Touches the core local dev proxy and HTML rewriting path; mistakes could break all proxied traffic or corrupt injected scripts, but changes are narrowly scoped with dedicated regression tests.
Overview
Fixes two regressions that made
raisely localhang on proxied requests and silently skip local page overrides.Proxy: Introduces
createCampaignProxyand wires the response interceptor underon: { proxyRes }(http-proxy-middleware v3). The old top-levelonProxyReswas ignored whileselfHandleResponsestill applied, so nothing wrote a response.HTML injection: Introduces
injectPageOverrideand usesString.replacereplacer functions (not replacement strings) when inserting the page-override script and related head/body patches, so copy with$1,$2,$&, etc. is not mangled. The main dev server path now calls these helpers instead of inlined replace logic.Adds
tests/local-proxy.test.jswith regression coverage for dollar-sign payloads, injection placement, and a live proxy round-trip.Reviewed by Cursor Bugbot for commit cbb9608. Bugbot is set up for automated code reviews on this repo. Configure here.