diff --git a/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb b/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb index 9c316cd2..649fc1b7 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb @@ -12,7 +12,15 @@ class << self sig { returns(RunnerClient) } def create_client - new + if File.exist?("bin/rails") + new + else + warn(<<~MSG) + Ruby LSP Rails failed to locate bin/rails in the current directory: #{Dir.pwd}" + MSG + warn("Server dependent features will not be available") + NullClient.new + end rescue Errno::ENOENT, StandardError => e # rubocop:disable Lint/ShadowedException warn("Ruby LSP Rails failed to initialize server: #{e.message}\n#{e.backtrace&.join("\n")}") warn("Server dependent features will not be available") diff --git a/test/ruby_lsp_rails/runner_client_test.rb b/test/ruby_lsp_rails/runner_client_test.rb index 92f96717..ff96f8e2 100644 --- a/test/ruby_lsp_rails/runner_client_test.rb +++ b/test/ruby_lsp_rails/runner_client_test.rb @@ -39,10 +39,28 @@ class RunnerClientTest < ActiveSupport::TestCase assert_nil @client.model("ApplicationRecord") # ApplicationRecord is abstract end + test "falls back to null client when bin/rails is not found" do + FileUtils.mv("bin/rails", "bin/rails_backup") + + assert_output("", %r{Ruby LSP Rails failed to locate bin/rails in the current directory}) do + client = RunnerClient.create_client + + assert_instance_of(NullClient, client) + assert_nil(client.model("User")) + assert_predicate(client, :stopped?) + end + ensure + FileUtils.mv("bin/rails_backup", "bin/rails") + end + test "failing to spawn server creates a null client" do FileUtils.mv("bin/rails", "bin/rails_backup") + File.open("bin/rails", "w") do |f| + f.write("foo") + end + File.chmod(0o755, "bin/rails") - assert_output("", %r{No such file or directory - bin/rails}) do + assert_output("", %r{uby LSP Rails failed to initialize server: bin/rails: line 1: foo: command not found}) do client = RunnerClient.create_client assert_instance_of(NullClient, client)