diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 394b85e45..abd817315 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -1388,6 +1388,9 @@ def compose_bundle(message) rescue Bundler::LockfileError => e send_message(Error.new(id: id, code: BUNDLE_COMPOSE_FAILED_CODE, message: e.message)) return + rescue Errno::EPERM + # If the user doesn't have permission to perform read operations, we can't compose the bundle + return rescue Bundler::GemfileNotFound, Errno::ENOENT # We still compose the bundle if there's no Gemfile or if the lockfile got deleted end diff --git a/test/server_test.rb b/test/server_test.rb index 928371e09..988a8e621 100644 --- a/test/server_test.rb +++ b/test/server_test.rb @@ -1214,6 +1214,36 @@ def test_compose_bundle_does_not_fail_if_restarting_on_lockfile_deletion end end + def test_compose_bundle_does_not_fail_if_user_does_not_have_permission_to_read_lockfile + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + @server.process_message({ + id: 1, + method: "initialize", + params: { + initializationOptions: {}, + capabilities: { general: { positionEncodings: ["utf-8"] } }, + workspaceFolders: [{ uri: URI::Generic.from_path(path: dir).to_s }], + }, + }) + + File.write(File.join(dir, "Gemfile"), <<~GEMFILE) + source "https://rubygems.org" + gem "stringio" + GEMFILE + + system("chmod 0000", Bundler.default_lockfile.to_s) + + capture_subprocess_io do + @server.send(:compose_bundle, { id: 2, method: "rubyLsp/composeBundle" })&.join + end + + result = find_message(RubyLsp::Result, id: 2) + assert(result.response[:success]) + end + end + end + def test_does_not_index_on_did_change_watched_files_if_document_is_managed_by_client path = File.join(Dir.pwd, "lib", "foo.rb") source = <<~RUBY