standardrb / vscode-standard-ruby

The official VS Code extension for the Standard Ruby linter and code formatter
Other
101 stars 7 forks source link

Saving is blocked forever when RuboCop::Runner::InfiniteCorrectionLoop is raised in the server #21

Open henrahmagix opened 6 months ago

henrahmagix commented 6 months ago

To replicate, use the file example here: https://github.com/standardrb/standard/issues/598

# infinite.rb
class MyClass
  def thing
    @thing ||= class << Object.new
      puts "self: #{self}"
    end
  end
end

MyClass.new.thing

I'm running v0.0.16 of this extension – which is fab otherwise!

Basically, when saving this file with this extension auto-formatting it, the file never saves and VS Code shows a popup that this extension is still formatting it. The output of the server shows the error is raised almost immediately, and then nothing, so it must mean that VS Code is waiting for some output, or cancellation. I have to click "cancel" in the popup for the file to then get saved.

image

Is there anything this extension can do if an error is raised by file correction, to just allow the file to be saved without formatting?


Extension output - click/toggle to expand ``` [client] Restarting language server... [client] Stopping language server... [server] Client asked to shutdown Standard LSP server. [server] Exiting... [client] Starting language server: bundle exec standardrb --lsp [server] Standard Ruby v1.32.1 LSP server initialized, pid 21237 [server] Error RuboCop::Runner::InfiniteCorrectionLoop Infinite loop detected in /me/standardrb-infinite-loop-test/infinite.rb and caused by Layout/EndAlignme [server] ["/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:332:in `check_for_infinite_loop'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:315:in `block in iterate_until_no_changes'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:314:in `loop'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:314:in `iterate_until_no_changes'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:283:in `do_inspection_loop'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:164:in `block in file_offenses'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:189:in `file_offense_cache'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:163:in `file_offenses'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:154:in `process_file'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:135:in `block in each_inspected_file'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:134:in `each'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:134:in `reduce'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:134:in `each_inspected_file'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:120:in `inspect_files'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/runner.rb:73:in `run'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/cli/command/execute_runner.rb:26:in `block in execute_runner'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/cli/command/execute_runner.rb:52:in `with_redirect'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/cli/command/execute_runner.rb:25:in `execute_runner'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/rubocop-1.57.2/lib/rubocop/cli/command/execute_runner.rb:17:in `run'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/runners/rubocop.rb:15:in `call'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/lsp/standardizer.rb:62:in `capture_rubocop_stdout'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/lsp/standardizer.rb:25:in `format'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/lsp/routes.rb:150:in `format_file'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/lsp/routes.rb:78:in `block in '", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/lsp/server.rb:25:in `call'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/lsp/server.rb:25:in `block in start'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/language_server-protocol-3.17.0.3/lib/language_server/protocol/transport/io/reader.rb:20:in `read'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/lsp/server.rb:21:in `start'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/runners/lsp.rb:7:in `call'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/lib/standard/cli.rb:14:in `run'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/standard-1.32.1/exe/standardrb:7:in `'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/bin/standardrb:25:in `load'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/bin/standardrb:25:in `'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/cli/exec.rb:58:in `load'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/cli/exec.rb:58:in `kernel_load'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/cli/exec.rb:23:in `run'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/cli.rb:492:in `exec'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/cli.rb:34:in `dispatch'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/cli.rb:28:in `start'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/exe/bundle:37:in `block in '", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/gems/bundler-2.4.19/exe/bundle:29:in `'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/bin/bundle:25:in `load'", "/me/.rbenv/versions/3.2.2/gemsets/standardrb-infinite-loop-test/bin/bundle:25:in `
'"] ```

My workspace settings:

        "standardRuby.mode": "enableUnconditionally",
        "[ruby]": {
            "editor.formatOnSave": true,
            "editor.defaultFormatter": "testdouble.vscode-standard-ruby"
        },

In the extension output, the error gets cut off in different ways, so it's not a typo or mis-copy on my behalf when the output above shows:

... caused by Layout/EndAlignme

In previous runs it's printed

... caused by L

which meant it took me a while to debug and figure out the cop causing the infinite loop, which I was able to do and created https://github.com/standardrb/standard/issues/598 to track a fix for the infinite loop itself.

So this issue is just related to unblocking VS Code file saving in this extension when it receives an error from standardrb/standard =)