Skip to content

Commit d415412

Browse files
committed
rescue serialization errors
1 parent f448c76 commit d415412

File tree

1 file changed

+97
-56
lines changed
  • apps/language_server/lib/language_server

1 file changed

+97
-56
lines changed

apps/language_server/lib/language_server/server.ex

Lines changed: 97 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -229,37 +229,42 @@ defmodule ElixirLS.LanguageServer.Server do
229229
{:ok, result} ->
230230
elapsed = System.monotonic_time(:millisecond) - start_time
231231

232-
# Use request module's result schematic if available (GenLSP requests)
233-
response_body =
234-
if function_exported?(request_module, :result, 0) do
235-
dumped_body =
236-
case SchematicV.dump(request_module.result(), result) do
237-
{:ok, dumped_body} ->
238-
dumped_body
239-
240-
{:error, error} ->
241-
IO.puts(
242-
:stderr,
243-
"Error dumping result: #{inspect(error)} for #{inspect(result)}"
244-
)
245-
246-
nil
247-
end
232+
try do
233+
response_body =
234+
if function_exported?(request_module, :result, 0) do
235+
{:ok, dumped_body} = SchematicV.dump(request_module.result(), result)
248236

249-
dumped_body
250-
else
251-
result
252-
end
237+
dumped_body
238+
else
239+
result
240+
end
253241

254-
JsonRpc.respond(id, response_body)
242+
JsonRpc.respond(id, response_body)
255243

256-
JsonRpc.telemetry(
257-
"lsp_request",
258-
%{"elixir_ls.lsp_command" => String.replace(command, "/", "_")},
259-
%{
260-
"elixir_ls.lsp_request_time" => elapsed
261-
}
262-
)
244+
JsonRpc.telemetry(
245+
"lsp_request",
246+
%{"elixir_ls.lsp_command" => String.replace(command, "/", "_")},
247+
%{
248+
"elixir_ls.lsp_request_time" => elapsed
249+
}
250+
)
251+
rescue
252+
error ->
253+
error_msg = Exception.format(:error, error, __STACKTRACE__)
254+
Logger.error("Error serializing response: #{error_msg} for #{inspect(result)}")
255+
256+
JsonRpc.respond_with_error(id, :internal_error, "Response serialization failed")
257+
258+
JsonRpc.telemetry(
259+
"lsp_request_error",
260+
%{
261+
"elixir_ls.lsp_command" => String.replace(command, "/", "_"),
262+
"elixir_ls.lsp_error" => "serialization_error",
263+
"elixir_ls.lsp_error" => error_msg
264+
},
265+
%{}
266+
)
267+
end
263268
end
264269

265270
Map.delete(state.requests_ids_by_pid, pid)
@@ -893,20 +898,38 @@ defmodule ElixirLS.LanguageServer.Server do
893898
request_module = struct.__struct__
894899
{:ok, result, state} = handle_request(struct, state)
895900
elapsed = System.monotonic_time(:millisecond) - start_time
896-
# Use request module's result schematic if available (GenLSP requests)
897-
response_body =
898-
if function_exported?(request_module, :result, 0) do
899-
{:ok, dumped_body} = SchematicV.dump(request_module.result(), result)
900-
dumped_body
901-
else
902-
result
903-
end
904901

905-
JsonRpc.respond(id, response_body)
902+
try do
903+
response_body =
904+
if function_exported?(request_module, :result, 0) do
905+
{:ok, dumped_body} = SchematicV.dump(request_module.result(), result)
906+
dumped_body
907+
else
908+
result
909+
end
910+
911+
JsonRpc.respond(id, response_body)
912+
913+
JsonRpc.telemetry("lsp_request", %{"elixir_ls.lsp_command" => "initialize"}, %{
914+
"elixir_ls.lsp_request_time" => elapsed
915+
})
916+
rescue
917+
error ->
918+
error_msg = Exception.format(:error, error, __STACKTRACE__)
919+
Logger.error("Error serializing response: #{error_msg} for #{inspect(result)}")
906920

907-
JsonRpc.telemetry("lsp_request", %{"elixir_ls.lsp_command" => "initialize"}, %{
908-
"elixir_ls.lsp_request_time" => elapsed
909-
})
921+
JsonRpc.respond_with_error(id, :internal_error, "Response serialization failed")
922+
923+
JsonRpc.telemetry(
924+
"lsp_request_error",
925+
%{
926+
"elixir_ls.lsp_command" => "initialize",
927+
"elixir_ls.lsp_error" => "serialization_error",
928+
"elixir_ls.lsp_error" => error_msg
929+
},
930+
%{}
931+
)
932+
end
910933

911934
state
912935
catch
@@ -1001,24 +1024,42 @@ defmodule ElixirLS.LanguageServer.Server do
10011024
# Store the request module for proper result encoding
10021025
request_module = struct.__struct__
10031026
elapsed = System.monotonic_time(:millisecond) - start_time
1004-
# Use request module's result schematic if available (GenLSP requests)
1005-
response_body =
1006-
if function_exported?(request_module, :result, 0) do
1007-
{:ok, dumped_body} = SchematicV.dump(request_module.result(), result)
1008-
dumped_body
1009-
else
1010-
result
1011-
end
10121027

1013-
JsonRpc.respond(id, response_body)
1028+
try do
1029+
response_body =
1030+
if function_exported?(request_module, :result, 0) do
1031+
{:ok, dumped_body} = SchematicV.dump(request_module.result(), result)
1032+
dumped_body
1033+
else
1034+
result
1035+
end
10141036

1015-
JsonRpc.telemetry(
1016-
"lsp_request",
1017-
%{"elixir_ls.lsp_command" => String.replace(command, "/", "_")},
1018-
%{
1019-
"elixir_ls.lsp_request_time" => elapsed
1020-
}
1021-
)
1037+
JsonRpc.respond(id, response_body)
1038+
1039+
JsonRpc.telemetry(
1040+
"lsp_request",
1041+
%{"elixir_ls.lsp_command" => String.replace(command, "/", "_")},
1042+
%{
1043+
"elixir_ls.lsp_request_time" => elapsed
1044+
}
1045+
)
1046+
rescue
1047+
error ->
1048+
error_msg = Exception.format(:error, error, __STACKTRACE__)
1049+
Logger.error("Error serializing response: #{error_msg} for #{inspect(result)}")
1050+
1051+
JsonRpc.respond_with_error(id, :internal_error, "Response serialization failed")
1052+
1053+
JsonRpc.telemetry(
1054+
"lsp_request_error",
1055+
%{
1056+
"elixir_ls.lsp_command" => String.replace(command, "/", "_"),
1057+
"elixir_ls.lsp_error" => "serialization_error",
1058+
"elixir_ls.lsp_error" => error_msg
1059+
},
1060+
%{}
1061+
)
1062+
end
10221063

10231064
state
10241065

0 commit comments

Comments
 (0)