Skip to content

Commit

Permalink
Avoid failing if file is quickly created and deleted (#3105)
Browse files Browse the repository at this point in the history
### Motivation

I noticed that we were crashing if a file was quickly created and deleted. Before we got to processing the created notification, the file would already no longer be there and trying to read from disk would raise.

This can happen when running tests that automatically created/delete files or if switching branches quickly.

### Implementation

Just started rescuing `Errno::ENOENT`. If the file is no longer there, it probably means we just haven't processed its deleted notification.

### Automated Tests

Added a test that fails before the fix.
  • Loading branch information
vinistock committed Jan 29, 2025
1 parent 0330a17 commit 9f0f8f2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/ruby_lsp/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,10 @@ def handle_ruby_file_change(index, file_path, change_type)
when Constant::FileChangeType::DELETED
index.delete(uri)
end
rescue Errno::ENOENT
# If a file is created and then delete immediately afterwards, we will process the created notification before we
# receive the deleted one, but the file no longer exists. This may happen when running a test suite that creates
# and deletes files automatically.
end

sig { params(uri: URI::Generic).void }
Expand Down
21 changes: 21 additions & 0 deletions test/server_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,27 @@ def test_changed_file_only_indexes_ruby
FileUtils.rm(T.must(path))
end

def test_did_change_watched_files_does_not_fail_for_non_existing_files
@server.process_message({
method: "workspace/didChangeWatchedFiles",
params: {
changes: [
{
uri: URI::Generic.from_path(path: File.join(Dir.pwd, "lib", "non_existing.rb")).to_s,
type: RubyLsp::Constant::FileChangeType::CREATED,
},
],
},
})

assert_raises(Timeout::Error) do
Timeout.timeout(0.5) do
notification = find_message(RubyLsp::Notification, "window/logMessage")
flunk(notification.params.message)
end
end
end

def test_workspace_addons
create_test_addons
@server.load_addons
Expand Down

0 comments on commit 9f0f8f2

Please sign in to comment.