diff --git a/lib/ruby_lsp/base_server.rb b/lib/ruby_lsp/base_server.rb index 98b26d0da..ace0addce 100644 --- a/lib/ruby_lsp/base_server.rb +++ b/lib/ruby_lsp/base_server.rb @@ -83,7 +83,7 @@ def start # The following requests need to be executed in the main thread directly to avoid concurrency issues. Everything # else is pushed into the incoming queue case method - when "initialize", "initialized", "rubyLsp/diagnoseState" + when "initialize", "initialized", "rubyLsp/diagnoseState", "$/cancelRequest" process_message(message) when "shutdown" @global_state.synchronize do @@ -154,20 +154,29 @@ def fail_request_and_notify(id, message, type: Constant::MessageType::INFO) def new_worker Thread.new do while (message = @incoming_queue.pop) - id = message[:id] - - # Check if the request was cancelled before trying to process it - @global_state.synchronize do - if id && @cancelled_requests.include?(id) - send_message(Result.new(id: id, response: nil)) - @cancelled_requests.delete(id) - next - end - end + handle_incoming_message(message) + end + end + end - process_message(message) + #: (Hash[Symbol, untyped]) -> void + def handle_incoming_message(message) + id = message[:id] + + # Check if the request was cancelled before trying to process it + @global_state.synchronize do + if id && @cancelled_requests.include?(id) + send_message(Error.new( + id: id, + code: Constant::ErrorCodes::REQUEST_CANCELLED, + message: "Request #{id} was cancelled", + )) + @cancelled_requests.delete(id) + return end end + + process_message(message) end #: ((Result | Error | Notification | Request) message) -> void diff --git a/test/server_test.rb b/test/server_test.rb index 928371e09..8ae300cd7 100644 --- a/test/server_test.rb +++ b/test/server_test.rb @@ -828,7 +828,7 @@ def handle_window_show_message_response(title) end end - def test_cancelling_requests_returns_nil + def test_cancelling_requests_returns_expected_error_code uri = URI("file:///foo.rb") @server.process_message({ @@ -868,8 +868,9 @@ def test_cancelling_requests_returns_nil mutex.unlock thread.join - result = find_message(RubyLsp::Result) - assert_nil(result.response) + error = find_message(RubyLsp::Error) + assert_equal(RubyLsp::Constant::ErrorCodes::REQUEST_CANCELLED, error.code) + assert_equal("Request 1 was cancelled", error.message) end def test_unsaved_changes_are_indexed_when_computing_automatic_features