Skip to content

fix: Ruby 3.4 compat — remove strip_heredoc, add missing GitUtils require#2599

Merged
justin808 merged 15 commits intomasterfrom
jg/2598-fix-turbo-streams
Mar 15, 2026
Merged

fix: Ruby 3.4 compat — remove strip_heredoc, add missing GitUtils require#2599
justin808 merged 15 commits intomasterfrom
jg/2598-fix-turbo-streams

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented Mar 13, 2026

Summary

  • Replace all <<-X.strip_heredoc with <<~X (squiggly heredoc) across 19 files
  • Remove redundant .strip_heredoc from <<~X.strip_heredoc patterns (e.g., license_public_key.rb, pro_helper.rb)
  • Add missing require "react_on_rails/git_utils" to install_generator.rb
  • Harden server_render_js non-Error throw serialization and add focused regression coverage

Problem

On Ruby 3.4, String#strip_heredoc from ActiveSupport is no longer automatically available, causing:

  1. undefined method 'strip_heredoc' in react_on_rails_pro/license_public_key.rb — Pro gem fails to load
  2. uninitialized constant ReactOnRails::GitUtils in the install generator — Pro install flow crashes

Fix

  • strip_heredoc: Ruby 2.3+ natively supports <<~X (squiggly heredoc) which does the same thing. This is a mechanical replacement with no behavior change.
  • GitUtils require: The install generator uses ReactOnRails::GitUtils at line 193 but never requires it. The main library loads it via react_on_rails.rb, but generators run in a context where the full library isn't loaded.

Test plan

  • RuboCop passes on all 19 changed files (verified locally + pre-push hook)
  • Ruby syntax check passes on all Pro files
  • CI should validate no regressions

Fixes #2598 (items 1 and 2 — strip_heredoc and GitUtils)

Note: Item 3 from the issue (RSC postcondition checks in create-react-on-rails-app --rsc) should be a separate PR.

🤖 Generated with Claude Code


Note

Low Risk
Mostly mechanical heredoc syntax changes with minimal behavioral impact; small risk limited to generators/test helpers if indentation/whitespace expectations differ.

Overview
Improves Ruby 3.4 compatibility by replacing <<-...strip_heredoc patterns with <<~... squiggly heredocs (and removing redundant .strip_heredoc chaining) across core helpers, configuration/messages, locale exporters, and specs.

Fixes the react_on_rails:install generator by explicitly requiring react_on_rails/git_utils, preventing ReactOnRails::GitUtils constant load errors when the generator runs outside the full library load path.

Written by Cursor Bugbot for commit 8a8d81a. Configure here.

Summary by CodeRabbit

  • New Features

    • Safer server-side rendering error handling: non-Error throws are serialized defensively, optional re-throwing, and structured error details returned with render output.
  • Chores

    • Standardized multiline string formatting across the codebase for consistent indentation and Ruby 3.4 compatibility.
    • Improved installer/load-path robustness.
  • Tests

    • Added/updated tests covering server-render error serialization and adjusted string expectations.

…uire

Replace all `<<-X.strip_heredoc` with `<<~X` (squiggly heredoc) and remove
redundant `.strip_heredoc` from `<<~X.strip_heredoc` patterns. The
`strip_heredoc` method from ActiveSupport is no longer automatically
available in Ruby 3.4, causing `undefined method` errors at runtime.

Also add missing `require "react_on_rails/git_utils"` to the install
generator, which caused `uninitialized constant ReactOnRails::GitUtils`
during Pro install flows.

Fixes #2598

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Standardized many heredocs to squiggly heredocs (<<~), added require "react_on_rails/git_utils" to the install generator, and hardened server_render_js error handling to safely serialize non-Error throws (or rethrow when configured). No public API signature changes.

Changes

Cohort / File(s) Summary
Generators & Install
react_on_rails/lib/generators/react_on_rails/install_generator.rb, react_on_rails/lib/generators/react_on_rails/base_generator.rb
Added require "react_on_rails/git_utils"; converted generator multiline constants from <<-...strip_heredoc to <<~ (whitespace/indentation normalization).
Server render & Helpers
react_on_rails/lib/react_on_rails/helper.rb, react_on_rails/lib/react_on_rails/packer_utils.rb, react_on_rails/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb
Switched heredocs to <<~; enhanced server_render_js error handling to either rethrow (when configured) or call ReactOnRails.handleError, set hasErrors, and include a renderingError object (message and optional stack) in the emitted payload.
Configuration & Test helpers
react_on_rails/lib/react_on_rails/configuration.rb, react_on_rails/lib/react_on_rails/test_helper.rb, react_on_rails/lib/react_on_rails/pro_helper.rb
Replaced strip_heredoc heredocs with <<~; minor adjustment to heredoc/html_safe construction in pro helper.
Locales / JS templates
react_on_rails/lib/react_on_rails/locales/base.rb, react_on_rails/lib/react_on_rails/locales/to_js.rb
Converted JS template heredocs to <<~ so generated JS has normalized indentation.
Tests & Specs
react_on_rails/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb, react_on_rails/spec/react_on_rails/support/generator_spec_helper.rb, react_on_rails/spec/react_on_rails/support/shared_examples/base_generator_examples.rb, react_on_rails/spec/react_on_rails/utils_spec.rb, react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb
Updated test fixtures to use squiggly heredocs; adjusted expectations for indentation changes; added spec(s) covering #server_render_js error serialization for non-Error throws (duplicate block noted).
Pro: License / Rake / Dummy app controllers
react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb, react_on_rails_pro/rakelib/public_key_management.rake, react_on_rails_pro/spec/dummy/app/controllers/application_controller.rb, react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb
Changed PEM/heredoc trimming to use .strip with <<~ (removes strip_heredoc usage); added structured prerender error handling helpers in dummy ApplicationController used by specs.
Spec support utilities
react_on_rails/spec/react_on_rails/support/...
Replaced strip_heredoc with <<~ for simulated file contents (e.g., package.json, generator matches) to normalize indentation in test fixtures.
Changelog
CHANGELOG.md
Added Unreleased notes: squiggly heredoc migration, install generator require for GitUtils, and defensive server_render_js handling for non-Error throws.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I tidy heredocs with a cheerful hop,
Squiggles line the fences—no more slop,
GitUtils hops in, errors wrapped with care,
Primitives now travel safe through SSR air,
A rabbit applauds: neat code, crunchy carrot!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes: removing strip_heredoc for Ruby 3.4 compatibility and adding a missing GitUtils require, matching the primary objectives.
Linked Issues check ✅ Passed The PR addresses the two critical coding objectives from #2598: replacing strip_heredoc for Ruby 3.4 compatibility across 19 files and adding the missing git_utils require to install_generator.rb.
Out of Scope Changes check ✅ Passed The PR scope is focused and appropriate. Changes replace strip_heredoc with squiggly heredocs and add the GitUtils require, with test updates reflecting the heredoc formatting changes only.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jg/2598-fix-turbo-streams
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 13, 2026

Review: Ruby 3.4 strip_heredoc<<~ Migration

Overall this is a well-targeted, low-risk fix for Ruby 3.4 compatibility. The mechanical replacement of <<-X.strip_heredoc with <<~X is semantically equivalent in all cases here, and removing .strip_heredoc from the already-squiggly <<~X.strip_heredoc patterns is correct (it was a no-op). The require "react_on_rails/git_utils" addition in install_generator.rb is a genuine fix for a constant-load bug in generator contexts.

A few things worth noting:

Potentially confusing PEM formatting (license_public_key.rb)

The -----BEGIN PUBLIC KEY----- line is indented 12 spaces in source while the key body lines are indented 6 spaces. With <<~PEM, stripping is based on the minimum (6), leaving -----BEGIN PUBLIC KEY----- with 6 residual leading spaces. The subsequent .strip removes them since it is the first line of the string — so the behaviour is correct — but the inconsistent source indentation is surprising and fragile if the file is ever re-indented. Consider normalising the PEM block indentation.

Unrelated rubocop suppression (application_controller.rb)

The # rubocop:disable Metrics/BlockLength / # rubocop:enable pair added around the rescue_from block appears unrelated to the heredoc migration. If this is needed to pass CI it should be called out explicitly in the PR description, or ideally addressed as a separate commit/PR so the intent is clear.

require style consistency (install_generator.rb)

The new require "react_on_rails/git_utils" sits among require_relative calls. This is fine (load-path require is the right idiom for a gem lib file), but a brief comment explaining why it can't be require_relative (e.g. "load-path require so it resolves correctly in generator contexts") would help future readers.

No behavioural regressions expected

  • All <<~ heredocs correctly strip to the minimum indentation of the block, matching strip_heredoc semantics for these inputs.
  • JavaScript string content in helper.rb is unchanged after indentation stripping.
  • Generated JSON in generator_spec_helper.rb is structurally identical.
  • The rake-task template in public_key_management.rake correctly propagates the updated <<~PEM.strip pattern into generated files.

Comment thread react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb Outdated
Comment thread react_on_rails_pro/spec/dummy/app/controllers/application_controller.rb Outdated
Comment thread react_on_rails/lib/generators/react_on_rails/install_generator.rb
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Mar 13, 2026

Greptile Summary

This PR fixes two Ruby 3.4 compatibility issues: it mechanically replaces all <<-X.strip_heredoc patterns with the native <<~X squiggly heredoc (supported since Ruby 2.3) across 19 files, and adds a missing require "react_on_rails/git_utils" to install_generator.rb which was crashing the Pro install flow with an uninitialized constant error when the full library wasn't pre-loaded.

Key changes:

  • <<-X.strip_heredoc<<~X (17 occurrences across lib, spec, and rake files): purely mechanical — both forms strip the common leading indentation and produce identical strings. All heredoc bodies were re-indented consistently.
  • <<~X.strip_heredoc<<~X (2 occurrences in pro_helper.rb and license_public_key.rb/public_key_management.rake): removes a now-redundant double-strip. Verified: for the PEM key in license_public_key.rb, <<~ strips 6 spaces (minimum indent of key-data lines), .strip removes the 6 residual spaces from the -----BEGIN PUBLIC KEY----- header line, producing valid PEM — identical to the old three-step <<~PEM.strip.strip_heredoc result.
  • require "react_on_rails/git_utils" in install_generator.rb: uses the same absolute require style as react_on_rails.rb (line 19) and correctly resolves to lib/react_on_rails/git_utils.rb via the gem load path. This is the appropriate fix since a require_relative path would be fragile across different load contexts.
  • A matching # rubocop:disable/enable Metrics/BlockLength pair was added around the rescue_from block in the Pro dummy application_controller.rb to suppress a pre-existing RuboCop warning surfaced by this diff.

Confidence Score: 5/5

  • This PR is safe to merge — all changes are mechanical string-equivalence replacements plus a targeted missing-require fix with no behavioral regressions.
  • Every strip_heredoc removal was independently verified to produce the same string output (same minimum indentation stripped). The PEM key transformation was traced step-by-step and remains valid. The require "react_on_rails/git_utils" addition follows the existing pattern in react_on_rails.rb and plugs a real crash. No logic, data, or contract changes were made. A full strip_heredoc grep confirms no occurrences remain.
  • No files require special attention.

Important Files Changed

Filename Overview
react_on_rails/lib/generators/react_on_rails/install_generator.rb Added require "react_on_rails/git_utils" to fix an uninitialized constant crash when the generator runs without the full library loaded. Require style matches react_on_rails.rb.
react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb Removed redundant .strip_heredoc from <<~PEM.strip.strip_heredoc. Verified: <<~ strips 6 spaces (minimum indent of key-data lines), .strip removes residual leading spaces from the header line, producing identical valid PEM as before.
react_on_rails_pro/rakelib/public_key_management.rake Removed redundant .strip_heredoc from the outer <<~RUBY template and the inner <<~PEM.strip template. The rake-generated license_public_key.rb will correctly produce valid PEM on the next update_public_key run.
react_on_rails/lib/react_on_rails/helper.rb Two <<-JS.strip_heredoc blocks converted to <<~JS. The generated JavaScript strings are identical; indentation was recalculated and consistent with squiggly-heredoc stripping.
react_on_rails/lib/react_on_rails/pro_helper.rb Removed redundant .strip_heredoc from <<~JS.strip_heredoc.html_safe. Behavior is unchanged since <<~ already strips indentation.
react_on_rails/lib/react_on_rails/configuration.rb Converted <<-MSG.strip_heredoc to <<~MSG. Message content is identical after re-indentation.
react_on_rails/lib/generators/react_on_rails/base_generator.rb Constants CONFIGURE_RSPEC_TO_COMPILE_ASSETS and CONFIGURE_MINITEST_TO_COMPILE_ASSETS migrated from <<-STR.strip_heredoc to <<~STR. Values are unchanged.
react_on_rails/lib/react_on_rails/packer_utils.rb Error message heredoc converted from <<-MSG.strip_heredoc to <<~MSG with re-indented content. Produces identical string.
react_on_rails/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb Diagnostic trace message migrated from <<-MSG.strip_heredoc to <<~MSG. No behavioral change.
react_on_rails/lib/react_on_rails/test_helper.rb Warning message migrated from <<-MSG.strip_heredoc to <<~MSG. No behavioral change.
react_on_rails/lib/react_on_rails/locales/base.rb Two template methods migrated from <<-JS.strip_heredoc to <<~JS. Generated locale file content is unchanged.
react_on_rails/lib/react_on_rails/locales/to_js.rb Same pattern as locales/base.rb — two template method heredocs migrated. No behavioral change.
react_on_rails/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb Five test fixture strings migrated from <<-SCRIPT.strip_heredoc to <<~SCRIPT. Expected strings are identical, so test assertions are unaffected.
react_on_rails/spec/react_on_rails/support/generator_spec_helper.rb JSON fixture string migrated from <<-JSON.strip_heredoc to <<~JSON. Re-indented content produces the same JSON string.
react_on_rails/spec/react_on_rails/support/shared_examples/base_generator_examples.rb Route-match fixture migrated from <<-MATCH.strip_heredoc to <<~MATCH. String content unchanged.
react_on_rails/spec/react_on_rails/utils_spec.rb Two test fixtures for wrap_message migrated from <<-MSG.strip_heredoc to <<~MSG. Content is identical so the test still asserts the same expected value.
react_on_rails_pro/spec/dummy/app/controllers/application_controller.rb Error message heredoc migrated from <<-MSG.strip_heredoc to <<~MSG; also added matching rubocop:disable/enable Metrics/BlockLength around the rescue_from block.
react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb Diagnostic log message migrated from <<-MSG.strip_heredoc to <<~MSG. No behavioral change.
react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb Two test fixture script tags migrated from <<-SCRIPT.strip_heredoc to <<~SCRIPT. Expected strings identical; no test assertion changes.

Sequence Diagram

sequenceDiagram
    participant Rails as Rails CLI
    participant IG as InstallGenerator
    participant GU as ReactOnRails::GitUtils
    participant GM as GeneratorMessages

    Rails->>IG: rails generate react_on_rails:install
    Note over IG: require "react_on_rails/git_utils"<br/>(NEW — fixes uninitialized constant crash)
    IG->>IG: installation_prerequisites_met?
    IG->>GU: uncommitted_changes?(GeneratorMessages)
    GU-->>IG: true / false
    alt uncommitted changes detected
        GU->>GM: add_error("You have uncommitted changes...")
        IG-->>Rails: prerequisites not met
    else clean working tree
        IG->>IG: invoke_generators
        IG-->>Rails: installation complete
    end
Loading

Last reviewed commit: 8a8d81a

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@react_on_rails/lib/react_on_rails/helper.rb`:
- Around line 234-237: The code currently assumes renderingError is an Error and
directly reads renderingError.message and renderingError.stack; change
renderingErrorObject creation to first guard that renderingError is an object
and not null (and has message/stack properties) before accessing them, otherwise
populate renderingErrorObject.message with String(renderingError) (or a fallback
like "Non-error thrown") and set stack to undefined/empty; ensure this logic is
used where throw_js_errors is false so non-Error throws (null, undefined,
primitives) do not cause a secondary exception while serializing renderingError.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e41a936e-23ca-4287-a91f-067e12d14577

📥 Commits

Reviewing files that changed from the base of the PR and between 13847ab and 8a8d81a.

📒 Files selected for processing (19)
  • react_on_rails/lib/generators/react_on_rails/base_generator.rb
  • react_on_rails/lib/generators/react_on_rails/install_generator.rb
  • react_on_rails/lib/react_on_rails/configuration.rb
  • react_on_rails/lib/react_on_rails/helper.rb
  • react_on_rails/lib/react_on_rails/locales/base.rb
  • react_on_rails/lib/react_on_rails/locales/to_js.rb
  • react_on_rails/lib/react_on_rails/packer_utils.rb
  • react_on_rails/lib/react_on_rails/pro_helper.rb
  • react_on_rails/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb
  • react_on_rails/lib/react_on_rails/test_helper.rb
  • react_on_rails/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
  • react_on_rails/spec/react_on_rails/support/generator_spec_helper.rb
  • react_on_rails/spec/react_on_rails/support/shared_examples/base_generator_examples.rb
  • react_on_rails/spec/react_on_rails/utils_spec.rb
  • react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb
  • react_on_rails_pro/rakelib/public_key_management.rake
  • react_on_rails_pro/spec/dummy/app/controllers/application_controller.rb
  • react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb
  • react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb

Comment thread react_on_rails/lib/react_on_rails/helper.rb Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 13, 2026

Review Summary

Overall this PR looks correct and well-scoped. The mechanical heredoc replacement is a clean Ruby 3.4 compatibility fix, and the missing require addition resolves a legitimate load-order bug in the install generator.

What looks good:

  • All heredoc conversions are behaviorally equivalent: <<~ strips common leading whitespace the same way <<-…strip_heredoc did, so no output changes are expected.
  • Removing the redundant .strip_heredoc from <<~PEM.strip.strip_heredoc is correct — <<~ already handled the indentation.
  • The require "react_on_rails/git_utils" fix is necessary: generators run before the full library is loaded, so relying on the transitive require from react_on_rails.rb is fragile.
  • The bonus bug-fix in server_render_js (guarding renderingError.message/.stack access for non-Error throws like throw null) is a real improvement.
  • The application_controller.rb extraction into private methods improves readability.

Minor issues:

  1. Debug puts statements left in placeputs "js_redirect" / puts js_redirect inside stream_prerender_error_response are pre-existing, but the refactor is a good opportunity to remove them. See inline comment.
  2. New spec tests string content, not behavior — The server_render_js error serialization spec asserts that the generated JS string contains certain substrings, which tightly couples the test to template wording rather than observed behavior. See inline comment.

No blocking issues — the core fixes are correct and low-risk.

Comment thread react_on_rails_pro/spec/dummy/app/controllers/application_controller.rb Outdated
@justin808 justin808 added the codex PRs created from codex-named branches label Mar 13, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@react_on_rails_pro/spec/dummy/app/controllers/application_controller.rb`:
- Around line 45-46: Remove the debug stdout prints in ApplicationController:
delete the two debug lines "puts \"js_redirect\"" and "puts js_redirect" (inside
the js_redirect handler/method in ApplicationController) so no debug output is
emitted in production; keep the original redirect/response behavior intact and
run tests to ensure no behavior changed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 97dfed15-ee1a-476c-8797-3ca2afa7b310

📥 Commits

Reviewing files that changed from the base of the PR and between 8a8d81a and c325598.

📒 Files selected for processing (5)
  • react_on_rails/lib/generators/react_on_rails/install_generator.rb
  • react_on_rails/lib/react_on_rails/helper.rb
  • react_on_rails/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
  • react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb
  • react_on_rails_pro/spec/dummy/app/controllers/application_controller.rb
🚧 Files skipped from review as they are similar to previous changes (2)
  • react_on_rails/lib/generators/react_on_rails/install_generator.rb
  • react_on_rails/lib/react_on_rails/helper.rb

Comment thread react_on_rails_pro/spec/dummy/app/controllers/application_controller.rb Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 13, 2026

Overall this is a clean and correct PR. The mechanical strip_heredoc to squiggly heredoc replacements are semantically equivalent and idiomatic for Ruby 2.3+. The require react_on_rails/git_utils fix addresses a real generator load-order issue.

Substantive change beyond the stated scope: helper.rb includes a genuine bug fix in server_render_js beyond the formatting change. The old code accessed renderingError.message and renderingError.stack directly, which throws TypeError if anything other than an Error object is thrown (e.g. throw null, throw 'string', throw 42). The new code defensively checks typeof renderingError === 'object' before accessing those properties, and falls back to String(renderingError). A corresponding test is added. Worth calling out in the PR description since it is a real behaviour change.

Debug output removed: application_controller.rb (pro spec dummy) removes leftover puts debug statements and refactors the rescue block into private methods — good housekeeping.

Minor nit: The comment added to install_generator.rb explaining the load-path require is helpful context.

Comment thread react_on_rails/lib/react_on_rails/helper.rb Outdated
Comment thread react_on_rails/lib/generators/react_on_rails/install_generator.rb
Comment thread CHANGELOG.md
Comment thread react_on_rails/lib/react_on_rails/helper.rb
Comment thread react_on_rails/lib/generators/react_on_rails/install_generator.rb
Comment thread react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 13, 2026

Review Summary

Overall this is a solid, well-scoped fix for Ruby 3.4 compatibility. The mechanical <<-X.strip_heredoc<<~X replacements are correct throughout, and the redundant .strip_heredoc removals on already-squiggly heredocs are accurate. A few points worth addressing before merge:

Must-fix

CHANGELOG — The single entry only documents the JS error-serialization improvement. The two Ruby 3.4 compat fixes (heredoc syntax + missing git_utils require) — which are the primary purpose of this PR — are completely absent from the changelog. See inline comment for a suggested expansion.

Worth addressing

  1. Scope / PR title mismatch — The diff contains three distinct changes:

    • Mechanical heredoc conversion (Ruby 3.4 compat) ✅
    • require "react_on_rails/git_utils" fix (Ruby 3.4 compat) ✅
    • New defensive JS error-serialization logic in helper.rb + a controller refactor in the Pro dummy app

    The title and PR description frame this as a Ruby 3.4 compat PR, but the JS error handling and ApplicationController refactoring are behavioural changes. That's fine to include, but the title/description should reflect it so reviewers know to evaluate those parts carefully.

  2. Test coverage for JS error handling — The new spec checks that certain strings appear in the generated JS, but never actually executes the JS. A throw null at runtime will only be proven safe by an integration/ExecJS-level test. See inline comment on the spec.

  3. stream_prerender_error_response stream safety — If response.stream.write raises (client disconnect), response.stream.close won't be called. Not introduced here, but worth fixing while refactoring. See inline comment on the controller.

Looks good

  • All <<~ conversions preserve indentation semantics correctly; <<~PEM.strip on the RSA public key is functionally identical to <<~PEM.strip.strip_heredoc.
  • The puts debug statements in the Pro dummy controller are correctly removed.
  • The rake task template for update_public_key was updated consistently with license_public_key.rb.
  • require "react_on_rails/git_utils" is the right fix for the generator load-path issue.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CHANGELOG.md`:
- Around line 28-31: Replace the incorrect Unreleased bullet about
`server_render_js` with a concise entry describing the actual user-visible fixes
from this PR: note the Ruby 3.4 compatibility fix for `strip_heredoc` and the
addition of an explicit `require "react_on_rails/git_utils"` (or
`ReactOnRails::GitUtils` require) in the install generator; remove the unrelated
`server_render_js` sentence and ensure the new changelog line references that
these are bugfixes and cites the PR/author as the existing entry format does.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 396d0240-952a-4351-a15f-f0493274fe03

📥 Commits

Reviewing files that changed from the base of the PR and between 68dc723 and 3aea325.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • react_on_rails/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • react_on_rails/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb

Comment thread CHANGELOG.md
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 13, 2026

PR Review: Solid Ruby 3.4 compatibility fix. Heredoc conversion is mechanical and correct, GitUtils require fix is legitimate, non-Error throw hardening in server_render_js addresses a real crash path. Positives: squiggly heredoc is semantically identical to strip_heredoc in every case, removing .strip_heredoc after squiggly PEM heredoc is correct, application_controller.rb refactoring removes debug puts and adds ensure for stream closure. Issues noted in inline comments: (1) rescue ExecJS::ProgramError before rescue StandardError looks like a no-op but is load-bearing - without it ProgramError falls into the StandardError branch and gets re-wrapped. Needs a clarifying comment. (2) eval comment says no user-provided input but generatedCode contains the interpolated js_expression. (3) ExecJS.compile bootstrap duplicated verbatim in both test cases, should be a shared let block. (4) Minor: extra blank line in generated JS in server_render_js.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 13, 2026

Review: Ruby 3.4 Compatibility — strip_heredoc + GitUtils + non-Error SSR throws

Overall this is a well-scoped, low-risk fix. The three concerns it addresses are real and the solutions are mechanically correct. A few notes below.

✅ What's solid

  • Heredoc migration (<<-X.strip_heredoc<<~X): Every conversion is semantically equivalent. <<~ strips minimum leading whitespace natively (Ruby 2.3+), which is exactly what strip_heredoc did. No output changes.
  • <<~PEM.strip.strip_heredoc<<~PEM.strip in license_public_key.rb: Correct removal — since the PEM body lines share uniform indentation, <<~ handles the stripping; the trailing .strip_heredoc was genuinely a no-op.
  • require "react_on_rails/git_utils" in install_generator.rb: Correct fix for the load-path gap. require is idempotent so there's no double-load risk.
  • ensure for response.stream.close in application_controller.rb: Genuine improvement — guarantees the stream is closed even if stream.write raises, removing a resource-leak path in the original.
  • err.backtrace&.join("\n"): Good nil-safety guard; some exception types can have a nil backtrace.
  • Removal of puts "js_redirect" debug lines: Clean-up of leaked debug output.

⚠️ Issues

See inline comments for specifics. Short summary:

  1. renderingErrorObject = { ... } in the generated JS is missing a trailing semicolon (ASI saves it, but the surrounding code uses explicit semicolons — inconsistent).
  2. The second spec test (raises PrerenderError when throw_js_errors is true) contains dead/unreachable code and unnecessarily complex rescue chains.

ℹ️ Minor nit

renderingError.stack != null (loose equality) is actually intentional here — it guards against both null and undefined, which is the right behaviour. A comment explaining this would prevent future readers from "fixing" it to !==.

Comment thread react_on_rails/lib/react_on_rails/helper.rb Outdated
Comment thread react_on_rails/lib/react_on_rails/helper.rb
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 13, 2026

Overall: Clean, well-motivated fix for real Ruby 3.4 breakage. Most changes are mechanical and correct.

Heredoc conversions: All replacements look correct. One case in license_public_key.rb is not purely mechanical (see inline comment) -- the old code had inconsistent indentation where the PEM header lines were indented further than the body content, so those lines still carried extra leading spaces after <<~PEM normalization. The new code aligns all PEM lines consistently, which is a latent correctness fix worth noting in the PR description.

server_render_js non-Error throw handling: Meaningful safety improvement. The old code accessed renderingError.message and renderingError.stack unconditionally, which raises TypeError for throw null, throw 42, throw string primitives, etc. The new typeof/in guards handle all these cases correctly.

GitUtils require fix: Correct. Generators run in a standalone context and cannot rely on full library boot loading ReactOnRails::GitUtils as a side effect.

ApplicationController refactor: Clean extraction into private methods. Moving response.stream.close into an ensure block is a real resource-safety fix -- the stream is now guaranteed to close even if an exception occurs while writing the error HTML. The backtrace safe-navigation fix is also correct (backtrace can be nil for some exception types).

Tests: The new spec covering throw null, plain-object throws, Error throws, and re-throw behavior when throw_js_errors is true is solid. Validating the generated JS behavior through ExecJS before Ruby post-processing is a good approach.

Comment thread react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb
Comment thread react_on_rails/lib/react_on_rails/helper.rb
@justin808 justin808 merged commit 67943d1 into master Mar 15, 2026
56 checks passed
@justin808 justin808 deleted the jg/2598-fix-turbo-streams branch March 15, 2026 01:05
justin808 added a commit that referenced this pull request Mar 30, 2026
…uire (#2599)

## Summary

- Replace all `<<-X.strip_heredoc` with `<<~X` (squiggly heredoc) across
19 files
- Remove redundant `.strip_heredoc` from `<<~X.strip_heredoc` patterns
(e.g., `license_public_key.rb`, `pro_helper.rb`)
- Add missing `require "react_on_rails/git_utils"` to
`install_generator.rb`
- Harden `server_render_js` non-Error throw serialization and add
focused regression coverage

## Problem

On Ruby 3.4, `String#strip_heredoc` from ActiveSupport is no longer
automatically available, causing:
1. `undefined method 'strip_heredoc'` in
`react_on_rails_pro/license_public_key.rb` — Pro gem fails to load
2. `uninitialized constant ReactOnRails::GitUtils` in the install
generator — Pro install flow crashes

## Fix

- **strip_heredoc**: Ruby 2.3+ natively supports `<<~X` (squiggly
heredoc) which does the same thing. This is a mechanical replacement
with no behavior change.
- **GitUtils require**: The install generator uses
`ReactOnRails::GitUtils` at line 193 but never requires it. The main
library loads it via `react_on_rails.rb`, but generators run in a
context where the full library isn't loaded.

## Test plan

- [x] RuboCop passes on all 19 changed files (verified locally +
pre-push hook)
- [x] Ruby syntax check passes on all Pro files
- [ ] CI should validate no regressions

Fixes #2598 (items 1 and 2 — strip_heredoc and GitUtils)

> Note: Item 3 from the issue (RSC postcondition checks in
`create-react-on-rails-app --rsc`) should be a separate PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Mostly mechanical heredoc syntax changes with minimal behavioral
impact; small risk limited to generators/test helpers if
indentation/whitespace expectations differ.
> 
> **Overview**
> Improves Ruby 3.4 compatibility by replacing `<<-...strip_heredoc`
patterns with `<<~...` squiggly heredocs (and removing redundant
`.strip_heredoc` chaining) across core helpers, configuration/messages,
locale exporters, and specs.
> 
> Fixes the `react_on_rails:install` generator by explicitly requiring
`react_on_rails/git_utils`, preventing `ReactOnRails::GitUtils` constant
load errors when the generator runs outside the full library load path.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8a8d81a. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Safer server-side rendering error handling: non-Error throws are
serialized defensively, optional re-throwing, and structured error
details returned with render output.

* **Chores**
* Standardized multiline string formatting across the codebase for
consistent indentation and Ruby 3.4 compatibility.
  * Improved installer/load-path robustness.

* **Tests**
* Added/updated tests covering server-render error serialization and
adjusted string expectations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
justin808 added a commit that referenced this pull request Apr 6, 2026
…uire (#2599)

## Summary

- Replace all `<<-X.strip_heredoc` with `<<~X` (squiggly heredoc) across
19 files
- Remove redundant `.strip_heredoc` from `<<~X.strip_heredoc` patterns
(e.g., `license_public_key.rb`, `pro_helper.rb`)
- Add missing `require "react_on_rails/git_utils"` to
`install_generator.rb`
- Harden `server_render_js` non-Error throw serialization and add
focused regression coverage

## Problem

On Ruby 3.4, `String#strip_heredoc` from ActiveSupport is no longer
automatically available, causing:
1. `undefined method 'strip_heredoc'` in
`react_on_rails_pro/license_public_key.rb` — Pro gem fails to load
2. `uninitialized constant ReactOnRails::GitUtils` in the install
generator — Pro install flow crashes

## Fix

- **strip_heredoc**: Ruby 2.3+ natively supports `<<~X` (squiggly
heredoc) which does the same thing. This is a mechanical replacement
with no behavior change.
- **GitUtils require**: The install generator uses
`ReactOnRails::GitUtils` at line 193 but never requires it. The main
library loads it via `react_on_rails.rb`, but generators run in a
context where the full library isn't loaded.

## Test plan

- [x] RuboCop passes on all 19 changed files (verified locally +
pre-push hook)
- [x] Ruby syntax check passes on all Pro files
- [ ] CI should validate no regressions

Fixes #2598 (items 1 and 2 — strip_heredoc and GitUtils)

> Note: Item 3 from the issue (RSC postcondition checks in
`create-react-on-rails-app --rsc`) should be a separate PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Mostly mechanical heredoc syntax changes with minimal behavioral
impact; small risk limited to generators/test helpers if
indentation/whitespace expectations differ.
> 
> **Overview**
> Improves Ruby 3.4 compatibility by replacing `<<-...strip_heredoc`
patterns with `<<~...` squiggly heredocs (and removing redundant
`.strip_heredoc` chaining) across core helpers, configuration/messages,
locale exporters, and specs.
> 
> Fixes the `react_on_rails:install` generator by explicitly requiring
`react_on_rails/git_utils`, preventing `ReactOnRails::GitUtils` constant
load errors when the generator runs outside the full library load path.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8a8d81a. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Safer server-side rendering error handling: non-Error throws are
serialized defensively, optional re-throwing, and structured error
details returned with render output.

* **Chores**
* Standardized multiline string formatting across the codebase for
consistent indentation and Ruby 3.4 compatibility.
  * Improved installer/load-path robustness.

* **Tests**
* Added/updated tests covering server-render error serialization and
adjusted string expectations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex PRs created from codex-named branches

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docs validation findings: Pro install failures + --rsc partial setup

1 participant