From fa8787f7c274ec9cbcad15ef31446a578d3ae4a7 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Fri, 28 Aug 2026 17:06:09 -0400 Subject: [PATCH 1/2] fix: show protocol handshake failures on the page (#213) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The handshake throws during the first hook mount, so a mismatch left a blank page whose only explanation was a DevTools console message. Every fatal handshake path now routes through `throwVisibly()`, which paints a fixed `#shinyreact-fatal-error` banner (role="alert") carrying the same text before throwing: the major mismatch in either direction, and the npm build's missing-tag / missing-protocolVersion errors. Plain DOM, no dependency on Shiny being initialized — the reported failure is that client and server cannot talk to each other. Literals (both versions, `#shinyreact-config`, `@posit/shinyreact`) are marked with backticks and render as `` chips; the backticks are stripped from the thrown error and the console-only warning. Text is set with textContent, so a server-supplied version cannot inject markup. Colors are #7f1d1d on #fee2e2 (~9.5:1). Tests: unit coverage in config.test.ts for both mismatch directions, chip markup, HTML-injection safety, banner reuse, and throw/display parity; a Playwright e2e (apps/protocol_mismatch) asserting the banner is on screen and the app body never rendered. --- FEATURES.md | 19 ++++++ pkg-js/dist/shinyreact.js | 20 +++---- .../src/shiny-react/__tests__/config.test.ts | 59 +++++++++++++++++++ pkg-js/src/shiny-react/bookmark.ts | 14 +++-- pkg-js/src/shiny-react/config.ts | 59 ++++++++++++++++++- pkg-py/src/shinyreact/www/shinyreact.js | 20 +++---- .../playwright/apps/protocol_mismatch/app.py | 19 ++++++ .../apps/protocol_mismatch/www/app.js | 11 ++++ .../apps/protocol_mismatch/www/index.html | 10 ++++ .../playwright/test_protocol_mismatch.py | 33 +++++++++++ pkg-r/inst/lib/shiny/shinyreact.js | 20 +++---- 11 files changed, 246 insertions(+), 38 deletions(-) create mode 100644 pkg-py/tests/playwright/apps/protocol_mismatch/app.py create mode 100644 pkg-py/tests/playwright/apps/protocol_mismatch/www/app.js create mode 100644 pkg-py/tests/playwright/apps/protocol_mismatch/www/index.html create mode 100644 pkg-py/tests/playwright/test_protocol_mismatch.py diff --git a/FEATURES.md b/FEATURES.md index 55b7f1c8..c72d22ae 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -62,6 +62,25 @@ R has no e2e suite, so no `(e2e)` leaf covers R (issue #194). reader to upgrade the older side - equal majors means compatible, so client and server package releases need not be released in lockstep + - `[js]` every fatal handshake failure is visible on the page, not only in + DevTools (#213) + - before throwing, a fixed banner `