Skip to content

fix: read live request body from editor DOM instead of debounced ref - #176

Open
hongwei1 wants to merge 2 commits into
OpenBankProject:developfrom
hongwei1:fix/request-body-debounce-race
Open

fix: read live request body from editor DOM instead of debounced ref#176
hongwei1 wants to merge 2 commits into
OpenBankProject:developfrom
hongwei1:fix/request-body-debounce-race

Conversation

@hongwei1

@hongwei1 hongwei1 commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

The JSON request-body editor (json-editor-vue / vanilla-jsoneditor, text mode) syncs its content into the value actually sent on POST/PUT via onChange, which is debounced (defaults to 300ms, and still resolves asynchronously even with debounce set to 0). Submitting immediately after typing or programmatically setting the body can race ahead of that sync and send stale or empty content — the outgoing request ends up with no body at all, which the API then rejects with a JSON-format error that has nothing to do with the JSON actually shown in the editor.

Confirmed by capturing the outgoing request: with no delay after editing, postData was null; only after waiting past the debounce did it carry the full JSON.

Fix

Read the request body straight from the CodeMirror editor's DOM (.cm-content) at submit time instead of relying on the debounced exampleRequestBody ref. The editor's own DOM is updated synchronously on every edit, so this sidesteps the race entirely. Falls back to the existing ref if the editor node isn't found for any reason.

Update: a second, related bug surfaced during verification. CodeMirror virtualises rendering for long content — only the visible viewport is actually present in the DOM — so the DOM read above can come back truncated (and therefore invalid JSON) for a sufficiently long, unedited example body, even though the editor's actual document is complete. The truncated JSON then failed JSON.parse() downstream, which silently omits the body on a parse failure rather than erroring. Fixed by validating the DOM read is parseable before trusting it, falling back to the exampleRequestBody ref otherwise — which for an unedited pre-filled example still holds the complete text from the API response, untouched by CodeMirror's rendering.

Test plan

  • Manually reproduced the race (typed a body, clicked the method button immediately, got a misleading JSON-format error despite valid JSON in the editor)
  • Manually reproduced the truncation bug (a long, deeply-nested example body sent no request body at all even with zero edits and zero delay)
  • Verified both fixes via an automated Playwright suite driving 9 different endpoints (including one with a long, nested example body) through this exact UI flow with no artificial delay — all pass reliably across multiple consecutive runs
  • Confirmed existing behavior (typing, then waiting, then submitting) is unaffected

The JSON request-body editor (json-editor-vue / vanilla-jsoneditor) syncs
its content into the value used on submit via onChange, which is
debounced (defaults to 300ms, and still resolves asynchronously even at
debounce=0). Submitting immediately after editing the body could race
ahead of that sync and send stale or empty content, surfacing as a
misleading JSON-format error from the API even though the editor showed
valid JSON.

Read the request body straight from the CodeMirror editor's DOM instead,
which is updated synchronously on every edit, with a fallback to the
existing ref if the editor node isn't found.
CodeMirror virtualises rendering for long content -- only the visible
viewport is actually present in the DOM -- so getCurrentRequestBodyText()
reading .cm-content directly (from the previous fix in this branch) could
return truncated, invalid JSON for a sufficiently long example body. That
invalid JSON then failed JSON.parse() in the request layer, which silently
omits the body on a parse failure, sending no body at all.

Validate the DOM read is parseable before trusting it; fall back to the
exampleRequestBody ref otherwise, which for an unedited pre-filled example
still holds the complete text from the API response untouched by
CodeMirror's rendering.
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