Skip to content

Commit 5d6639f

Browse files
authored
Merge pull request #1209 from elixir-lsp/codex/introduce-incrementing-error-id-counter
Add error dictionary for DAP errors
2 parents 6813f21 + 0ed72cb commit 5d6639f

File tree

5 files changed

+92
-10
lines changed

5 files changed

+92
-10
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
defmodule ElixirLS.DebugAdapter.ErrorDictionary do
2+
@moduledoc """
3+
Provides mapping from error names to unique integer codes for DAP error messages.
4+
"""
5+
6+
@codes %{
7+
"internalServerError" => 1,
8+
"cancelled" => 2,
9+
"invalidRequest" => 3,
10+
"launchError" => 4,
11+
"attachError" => 5,
12+
"invalidArgument" => 6,
13+
"evaluateError" => 7,
14+
"argumentError" => 8,
15+
"runtimeError" => 9,
16+
"notSupported" => 10
17+
}
18+
19+
@spec code(String.t()) :: integer()
20+
def code(name) do
21+
Map.fetch!(@codes, name)
22+
end
23+
end

apps/debug_adapter/lib/debug_adapter/output.ex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ defmodule ElixirLS.DebugAdapter.Output do
2424
def send_error_response(
2525
server \\ __MODULE__,
2626
request_packet,
27+
error_code,
2728
message,
2829
format,
2930
variables,
@@ -32,8 +33,8 @@ defmodule ElixirLS.DebugAdapter.Output do
3233
) do
3334
GenServer.call(
3435
server,
35-
{:send_error_response, request_packet, message, format, variables, send_telemetry,
36-
show_user},
36+
{:send_error_response, request_packet, error_code, message, format, variables,
37+
send_telemetry, show_user},
3738
:infinity
3839
)
3940
end
@@ -142,8 +143,8 @@ defmodule ElixirLS.DebugAdapter.Output do
142143
end
143144

144145
def handle_call(
145-
{:send_error_response, request_packet, message, format, variables, send_telemetry,
146-
show_user},
146+
{:send_error_response, request_packet, error_code, message, format, variables,
147+
send_telemetry, show_user},
147148
_from,
148149
seq
149150
) do
@@ -159,8 +160,7 @@ defmodule ElixirLS.DebugAdapter.Output do
159160
message: message,
160161
body: %{
161162
error: %GenDAP.Structures.Message{
162-
# TODO unique ids
163-
id: 1,
163+
id: error_code,
164164
format: format,
165165
variables: variables,
166166
send_telemetry: send_telemetry,

apps/debug_adapter/lib/debug_adapter/protocol.basic.ex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ defmodule ElixirLS.DebugAdapter.Protocol.Basic do
5858
send_telemetry,
5959
show_user
6060
) do
61+
message_value = Macro.expand_once(message, __CALLER__)
62+
error_id =
63+
case message_value do
64+
value when is_binary(value) -> ElixirLS.DebugAdapter.ErrorDictionary.code(value)
65+
_ -> quote(do: ElixirLS.DebugAdapter.ErrorDictionary.code(unquote(message)))
66+
end
67+
6168
quote do
6269
%{
6370
"type" => "response",
@@ -68,7 +75,7 @@ defmodule ElixirLS.DebugAdapter.Protocol.Basic do
6875
"message" => unquote(message),
6976
"body" => %{
7077
"error" => %{
71-
"id" => unquote(seq),
78+
"id" => unquote(error_id),
7279
"format" => unquote(format),
7380
"variables" => unquote(variables),
7481
"showUser" => unquote(show_user),

apps/debug_adapter/lib/debug_adapter/server.ex

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ defmodule ElixirLS.DebugAdapter.Server do
2626
ModuleInfoCache,
2727
IdManager,
2828
VariableRegistry,
29-
ThreadRegistry
29+
ThreadRegistry,
30+
ErrorDictionary
3031
}
3132

3233
alias ElixirLS.DebugAdapter.Stacktrace.Frame
@@ -346,6 +347,7 @@ defmodule ElixirLS.DebugAdapter.Server do
346347
{:error, e = %ServerError{}} ->
347348
Output.send_error_response(
348349
packet,
350+
ErrorDictionary.code(e.message),
349351
e.message,
350352
e.format,
351353
e.variables,
@@ -497,6 +499,7 @@ defmodule ElixirLS.DebugAdapter.Server do
497499
e in ServerError ->
498500
Output.send_error_response(
499501
packet,
502+
ErrorDictionary.code(e.message),
500503
e.message,
501504
e.format,
502505
e.variables,
@@ -524,7 +527,17 @@ defmodule ElixirLS.DebugAdapter.Server do
524527

525528
message = Exception.format(kind, payload, stacktrace)
526529
Output.debugger_console(message)
527-
Output.send_error_response(packet, "internalServerError", message, %{}, true, false)
530+
531+
Output.send_error_response(
532+
packet,
533+
ErrorDictionary.code("internalServerError"),
534+
"internalServerError",
535+
message,
536+
%{},
537+
true,
538+
false
539+
)
540+
528541
{:noreply, state}
529542
end
530543
end
@@ -641,6 +654,7 @@ defmodule ElixirLS.DebugAdapter.Server do
641654

642655
Output.send_error_response(
643656
packet,
657+
ErrorDictionary.code("internalServerError"),
644658
"internalServerError",
645659
"Request handler exited with reason #{Exception.format_exit(reason)}",
646660
%{},
@@ -788,7 +802,16 @@ defmodule ElixirLS.DebugAdapter.Server do
788802
# flush as we are not interested in :DOWN message anymore
789803
Process.demonitor(ref, [:flush])
790804
Process.exit(pid, :cancelled)
791-
Output.send_error_response(packet, "cancelled", "cancelled", %{}, false, false)
805+
806+
Output.send_error_response(
807+
packet,
808+
ErrorDictionary.code("cancelled"),
809+
"cancelled",
810+
"cancelled",
811+
%{},
812+
false,
813+
false
814+
)
792815

793816
# send progressEnd if cancelling a progress
794817
updated_progresses =
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
defmodule ElixirLS.DebugAdapter.OutputTest do
2+
use ExUnit.Case, async: true
3+
import ElixirLS.DebugAdapter.Protocol.Basic
4+
5+
alias ElixirLS.DebugAdapter.Output
6+
7+
setup do
8+
{:ok, capture} = ElixirLS.Utils.PacketCapture.start_link(self())
9+
{:ok, output} = Output.start(:output_test)
10+
Process.group_leader(output, capture)
11+
12+
on_exit(fn ->
13+
if Process.alive?(output), do: GenServer.stop(output)
14+
end)
15+
16+
{:ok, %{output: output}}
17+
end
18+
19+
test "error response uses provided id", %{output: output} do
20+
req = request(1, "cmd")
21+
Output.send_error_response(output, req, 42, "err", "fmt", %{}, false, false)
22+
23+
assert_receive %{
24+
"body" => %{"error" => %{"id" => 42}},
25+
"seq" => 1,
26+
"request_seq" => 1
27+
}
28+
end
29+
end

0 commit comments

Comments
 (0)