Skip to content

Commit a348fec

Browse files
authored
Use different error code for code action errors (#2634)
1 parent 2e8ad8e commit a348fec

4 files changed

Lines changed: 45 additions & 30 deletions

File tree

lib/ruby_lsp/base_server.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ def process_message(message); end
130130
sig { abstract.void }
131131
def shutdown; end
132132

133+
sig { params(id: Integer, message: String, type: Integer).void }
134+
def fail_request_and_notify(id, message, type: Constant::MessageType::INFO)
135+
send_message(Error.new(id: id, code: Constant::ErrorCodes::REQUEST_FAILED, message: message))
136+
send_message(Notification.window_show_message(message, type: type))
137+
end
138+
133139
sig { returns(Thread) }
134140
def new_worker
135141
Thread.new do

lib/ruby_lsp/server.rb

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,9 @@ def run_initialized
285285
rescue RuboCop::Error => e
286286
# The user may have provided unknown config switches in .rubocop or
287287
# is trying to load a non-existant config file.
288-
send_message(Notification.window_show_error(
288+
send_message(Notification.window_show_message(
289289
"RuboCop configuration error: #{e.message}. Formatting will not be available.",
290+
type: Constant::MessageType::ERROR,
290291
))
291292
end
292293
end
@@ -531,10 +532,16 @@ def text_document_formatting(message)
531532
response = Requests::Formatting.new(@global_state, document).perform
532533
send_message(Result.new(id: message[:id], response: response))
533534
rescue Requests::Request::InvalidFormatter => error
534-
send_message(Notification.window_show_error("Configuration error: #{error.message}"))
535+
send_message(Notification.window_show_message(
536+
"Configuration error: #{error.message}",
537+
type: Constant::MessageType::ERROR,
538+
))
535539
send_empty_response(message[:id])
536540
rescue StandardError, LoadError => error
537-
send_message(Notification.window_show_error("Formatting error: #{error.message}"))
541+
send_message(Notification.window_show_message(
542+
"Formatting error: #{error.message}",
543+
type: Constant::MessageType::ERROR,
544+
))
538545
send_empty_response(message[:id])
539546
end
540547

@@ -673,30 +680,19 @@ def code_action_resolve(message)
673680
document = @store.get(uri)
674681

675682
unless document.is_a?(RubyDocument)
676-
send_message(Notification.window_show_error("Code actions are currently only available for Ruby documents"))
677-
raise Requests::CodeActionResolve::CodeActionError
683+
fail_request_and_notify(message[:id], "Code actions are currently only available for Ruby documents")
684+
return
678685
end
679686

680687
result = Requests::CodeActionResolve.new(document, params).perform
681688

682689
case result
683690
when Requests::CodeActionResolve::Error::EmptySelection
684-
send_message(Notification.window_show_error("Invalid selection for Extract Variable refactor"))
685-
raise Requests::CodeActionResolve::CodeActionError
691+
fail_request_and_notify(message[:id], "Invalid selection for extract variable refactor")
686692
when Requests::CodeActionResolve::Error::InvalidTargetRange
687-
send_message(
688-
Notification.window_show_error(
689-
"Couldn't find an appropriate location to place extracted refactor",
690-
),
691-
)
692-
raise Requests::CodeActionResolve::CodeActionError
693+
fail_request_and_notify(message[:id], "Couldn't find an appropriate location to place extracted refactor")
693694
when Requests::CodeActionResolve::Error::UnknownCodeAction
694-
send_message(
695-
Notification.window_show_error(
696-
"Unknown code action",
697-
),
698-
)
699-
raise Requests::CodeActionResolve::CodeActionError
695+
fail_request_and_notify(message[:id], "Unknown code action")
700696
else
701697
send_message(Result.new(id: message[:id], response: result))
702698
end
@@ -729,10 +725,16 @@ def text_document_diagnostic(message)
729725
),
730726
)
731727
rescue Requests::Request::InvalidFormatter => error
732-
send_message(Notification.window_show_error("Configuration error: #{error.message}"))
728+
send_message(Notification.window_show_message(
729+
"Configuration error: #{error.message}",
730+
type: Constant::MessageType::ERROR,
731+
))
733732
send_empty_response(message[:id])
734733
rescue StandardError, LoadError => error
735-
send_message(Notification.window_show_error("Error running diagnostics: #{error.message}"))
734+
send_message(Notification.window_show_message(
735+
"Error running diagnostics: #{error.message}",
736+
type: Constant::MessageType::ERROR,
737+
))
736738
send_empty_response(message[:id])
737739
end
738740

@@ -971,7 +973,7 @@ def perform_initial_indexing
971973
rescue StandardError => error
972974
message = "Error while indexing (see [troubleshooting steps]" \
973975
"(https://shopify.github.io/ruby-lsp/troubleshooting#indexing)): #{error.message}"
974-
send_message(Notification.window_show_error(message))
976+
send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR))
975977
end
976978

977979
# Indexing produces a high number of short lived object allocations. That might lead to some fragmentation and
@@ -1056,8 +1058,9 @@ def check_formatter_is_available
10561058
@global_state.formatter = "none"
10571059

10581060
send_message(
1059-
Notification.window_show_error(
1061+
Notification.window_show_message(
10601062
"Ruby LSP formatter is set to `rubocop` but RuboCop was not found in the Gemfile or gemspec.",
1063+
type: Constant::MessageType::ERROR,
10611064
),
10621065
)
10631066
end

lib/ruby_lsp/utils.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,11 @@ class Notification < Message
6464
class << self
6565
extend T::Sig
6666

67-
sig { params(message: String).returns(Notification) }
68-
def window_show_error(message)
67+
sig { params(message: String, type: Integer).returns(Notification) }
68+
def window_show_message(message, type: Constant::MessageType::INFO)
6969
new(
7070
method: "window/showMessage",
71-
params: Interface::ShowMessageParams.new(
72-
type: Constant::MessageType::ERROR,
73-
message: message,
74-
),
71+
params: Interface::ShowMessageParams.new(type: type, message: message),
7572
)
7673
end
7774

vscode/src/client.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
ClientCapabilities,
2828
FeatureState,
2929
ServerCapabilities,
30+
ErrorCodes,
3031
} from "vscode-languageclient/node";
3132

3233
import {
@@ -397,7 +398,15 @@ export default class Client extends LanguageClient implements ClientInterface {
397398
} else {
398399
const { errorMessage, errorClass, backtrace } = error.data;
399400

400-
if (errorMessage && errorClass && backtrace) {
401+
// We only want to produce telemetry events for errors that have all the data we need and that are internal
402+
// server errors. Other errors do not necessarily indicate bugs in the server. You can check LSP error codes
403+
// here https://microsoft.github.io/language-server-protocol/specification/#errorCodes
404+
if (
405+
errorMessage &&
406+
errorClass &&
407+
backtrace &&
408+
error.code === ErrorCodes.InternalError
409+
) {
401410
// Sanitize the backtrace coming from the server to remove the user's home directory from it, then mark it
402411
// as a trusted value. Otherwise the VS Code telemetry logger redacts the entire backtrace and we are unable
403412
// to see where in the server the error occurred

0 commit comments

Comments
 (0)