Skip to content

Commit bd1265e

Browse files
justin808claude
andcommitted
Fix RBS validation issues and improve error handling
- Replace Open3.capture3 timeout option with Timeout.timeout wrapper for Ruby 3.0+ compatibility - Remove duplicate RBS definitions for PrerenderError and JsonParseError from sig/react_on_rails.rbs - Add comment explaining error class definitions are in separate files - Improve test documentation with clearer explanation of RBS runtime checking - Add timeout handling to Pro package RBS rake tasks - Add RuboCop disable for BlockLength in Pro package RBS rake file The timeout option for Open3.capture3 was added in Ruby 3.3, but we support Ruby >= 3.0.0. Using Timeout.timeout provides compatibility across all supported Ruby versions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent ac47a6d commit bd1265e

File tree

4 files changed

+26
-31
lines changed

4 files changed

+26
-31
lines changed

rakelib/rbs.rake

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require "open3"
4+
require "timeout"
45

56
# rubocop:disable Metrics/BlockLength
67
namespace :rbs do
@@ -15,8 +16,10 @@ namespace :rbs do
1516
# This allows us to distinguish between actual validation errors and warnings
1617
# Note: Must use bundle exec even though rake runs in bundle context because
1718
# spawned shell commands via Open3.capture3() do NOT inherit bundle context
18-
# Timeout after 60 seconds to prevent hung processes in CI environments
19-
stdout, stderr, status = Open3.capture3("bundle exec rbs -I sig validate", timeout: 60)
19+
# Wrap in Timeout to prevent hung processes in CI environments (60 second timeout)
20+
stdout, stderr, status = Timeout.timeout(60) do
21+
Open3.capture3("bundle exec rbs -I sig validate")
22+
end
2023

2124
if status.success?
2225
puts "✓ RBS validation passed"
@@ -46,8 +49,10 @@ namespace :rbs do
4649
# Use Open3 for better error handling
4750
# Note: Must use bundle exec even though rake runs in bundle context because
4851
# spawned shell commands via Open3.capture3() do NOT inherit bundle context
49-
# Timeout after 60 seconds to prevent hung processes in CI environments
50-
stdout, stderr, status = Open3.capture3("bundle exec steep check", timeout: 60)
52+
# Wrap in Timeout to prevent hung processes in CI environments (60 second timeout)
53+
stdout, stderr, status = Timeout.timeout(60) do
54+
Open3.capture3("bundle exec steep check")
55+
end
5156

5257
if status.success?
5358
puts "✓ Steep type checking passed"

react_on_rails_pro/rakelib/rbs.rake

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# frozen_string_literal: true
22

33
require "open3"
4+
require "timeout"
45

56
# NOTE: Pro package does not include Steep tasks (:steep, :all) as it does not
67
# use Steep type checker. Only RBS validation is performed.
8+
# rubocop:disable Metrics/BlockLength
79
namespace :rbs do
810
desc "Validate RBS type signatures"
911
task :validate do
@@ -16,7 +18,10 @@ namespace :rbs do
1618
# This allows us to distinguish between actual validation errors and warnings
1719
# Note: Must use bundle exec even though rake runs in bundle context because
1820
# spawned shell commands via Open3.capture3() do NOT inherit bundle context
19-
stdout, stderr, status = Open3.capture3("bundle exec rbs -I sig validate")
21+
# Wrap in Timeout to prevent hung processes in CI environments (60 second timeout)
22+
stdout, stderr, status = Timeout.timeout(60) do
23+
Open3.capture3("bundle exec rbs -I sig validate")
24+
end
2025

2126
if status.success?
2227
puts "✓ RBS validation passed"
@@ -39,3 +44,4 @@ namespace :rbs do
3944
puts "\nTotal: #{sig_files.count} files"
4045
end
4146
end
47+
# rubocop:enable Metrics/BlockLength

sig/react_on_rails.rbs

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,9 @@ module ReactOnRails
99
def self.configure: () { (Configuration) -> void } -> void
1010
def self.configuration: () -> Configuration
1111

12+
# Error classes are defined in separate RBS files:
13+
# - sig/react_on_rails/prerender_error.rbs
14+
# - sig/react_on_rails/json_parse_error.rbs
1215
class Error < StandardError
1316
end
14-
15-
class PrerenderError < Error
16-
attr_reader component_name: String?
17-
attr_reader js_code: String?
18-
attr_reader err: Hash[Symbol, untyped]?
19-
attr_reader props: (Hash[Symbol, untyped] | String)?
20-
attr_reader console_messages: Array[String]?
21-
22-
def initialize: (
23-
?component_name: String?,
24-
?js_code: String?,
25-
?err: Hash[Symbol, untyped]?,
26-
?props: (Hash[Symbol, untyped] | String)?,
27-
?console_messages: Array[String]?
28-
) -> void
29-
30-
def to_honeybadger_context: () -> Hash[Symbol, untyped]
31-
def raven_context: () -> Hash[Symbol, untyped]
32-
def to_error_context: () -> Hash[Symbol, untyped]
33-
end
34-
35-
class JsonParseError < Error
36-
def initialize: (Hash[Symbol, untyped] err) -> void
37-
end
3817
end

spec/react_on_rails/rbs_runtime_checking_spec.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@
1515
it "catches invalid type assignments to configuration" do
1616
# This test verifies runtime checking actually works by intentionally
1717
# violating a type signature and expecting RBS to catch it
18-
# Type signature: sig/react_on_rails/configuration.rbs:4
19-
# attr_accessor server_bundle_js_file: String
18+
#
19+
# Type signature defined in: sig/react_on_rails/configuration.rbs
20+
# attr_accessor server_bundle_js_file: String
21+
#
22+
# When RBS runtime checking is enabled via rakelib/run_rspec.rake, the
23+
# RBS::Test::Hook wraps all method calls to ReactOnRails classes and validates
24+
# that arguments and return values match the type signatures.
2025
expect do
2126
config = ReactOnRails::Configuration.new(
2227
server_bundle_js_file: 123 # Invalid: should be String, not Integer

0 commit comments

Comments
 (0)