rspec doesn't work with Default gem SyntaxSuggest due to not-re-raising SyntaxError
schneems opened this issue · 2 comments
Subject of the issue
The default gem SyntaxSuggest (previously DeadEnd) works to find syntax errors in Ruby code and show you where the error likely lives. This was added in Ruby 3.2 which was just released. Prior to Ruby 3.2 it worked by hooking into require and load. With Ruby 3.2 it has a deeper integration with SyntaxError instead. So to get a helpful error result the SyntaxError must be raised.
This issue with RSpec was reported in ruby/syntax_suggest#171. Here's the root cause:
rspec-core/lib/rspec/core/configuration.rb
Lines 2123 to 2126 in 522b772
On these lines you can see that the error is swallowed and never re-raised. If you add this line at the end:
rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex
relative_file = Metadata.relative_path(file)
reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.")
RSpec.world.wants_to_quit = true
raise ex # <===== HEREThe output will be correct:
bundler: failed to load command: rspec (/Users/rubyku/.gem/ruby/3.2.0/bin/rspec)
/Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/configuration.rb:2117:in `load': --> /Users/rubyku/richard/projects/syntax_suggest_sandbox/spec/sample_spec.rb
Unmatched `end', missing keyword (`do', `def`, `if`, etc.) ?
1 RSpec.describe 'sample' do
> 2 exampledo
> 4 end
5 end
/Users/rubyku/richard/projects/syntax_suggest_sandbox/spec/sample_spec.rb:5: syntax error, unexpected `end' (SyntaxError)
Your environment
- Ruby version: 3.2.0
- rspec-core version: 3.12.0
Steps to reproduce
git clone https://github.com/JunichiIto/syntax_suggest_sandbox
cd syntax_suggest_sandbox
bundle install
bundle exec rspec
Expected behavior
bundler: failed to load command: rspec (/Users/rubyku/.gem/ruby/3.2.0/bin/rspec)
/Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/configuration.rb:2117:in `load': --> /Users/rubyku/richard/projects/syntax_suggest_sandbox/spec/sample_spec.rb
Unmatched `end', missing keyword (`do', `def`, `if`, etc.) ?
1 RSpec.describe 'sample' do
> 2 exampledo
> 4 end
5 end
/Users/rubyku/richard/projects/syntax_suggest_sandbox/spec/sample_spec.rb:5: syntax error, unexpected `end' (SyntaxError)
Actual behavior
$ bundle exec rspec
An error occurred while loading ./spec/sample_spec.rb.
Failure/Error: __send__(method, file)
SyntaxError:
/Users/rubyku/richard/projects/syntax_suggest_sandbox/spec/sample_spec.rb:5: syntax error, unexpected `end'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/configuration.rb:2117:in `load'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/configuration.rb:2117:in `load_file_handling_errors'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/configuration.rb:1617:in `block in load_spec_files'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/configuration.rb:1615:in `each'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/configuration.rb:1615:in `load_spec_files'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:102:in `setup'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:86:in `run'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:71:in `run'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:45:in `invoke'
# /Users/rubyku/.gem/ruby/3.2.0/gems/rspec-core-3.12.0/exe/rspec:4:in `<top (required)>'
# /Users/rubyku/.gem/ruby/3.2.0/bin/rspec:25:in `load'
# /Users/rubyku/.gem/ruby/3.2.0/bin/rspec:25:in `<top (required)>'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/cli/exec.rb:58:in `load'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/cli/exec.rb:58:in `kernel_load'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/cli/exec.rb:23:in `run'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/cli.rb:491:in `exec'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/cli.rb:34:in `dispatch'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/cli.rb:28:in `start'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.4.1/libexec/bundle:45:in `block in <top (required)>'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/3.2.0/bundler/friendly_errors.rb:117:in `with_friendly_errors'
# /Users/rubyku/.rubies/ruby-3.2.0/lib/ruby/gems/3.2.0/gems/bundler-2.4.1/libexec/bundle:33:in `<top (required)>'
# /Users/rubyku/.rubies/ruby-3.2.0/bin/bundle:25:in `load'
# /Users/rubyku/.rubies/ruby-3.2.0/bin/bundle:25:in `<main>'
I'm out on vacation right now with my family otherwise I would have sent a patch. I still wanted to leave an issue. Hopefully someone else can pick it up and test my one line fix to see if tests still pass. There is likely a good reason the error isn't re-raised which needs investigation and possibly some work. If no one can get to it, then I'll try to make a patch later, but it won't be soon.
I think we just need to add SyntaxError as a special case no? We don't want to raise other errors, thats the whole point of capturing them, so either we never rescue SyntaxError (add it to the list we already maintain for SystemExit et al) or we only re-raise that one error.
Seems good. If needed: We can also gate on the SyntaxError#respond_to?(:path) which is not present prior to Ruby 3.2