Fix JSON output for `rabbitmqctl environment`

Fixes #14101
This commit is contained in:
Luke Bakken 2025-06-24 13:20:26 -07:00
parent 754352375c
commit 75cd74a2f2
No known key found for this signature in database
GPG Key ID: D99DE30E43EAE440
1 changed files with 62 additions and 1 deletions

View File

@ -18,7 +18,7 @@ defmodule RabbitMQ.CLI.Formatters.Json do
end end
def format_output(output, _opts) do def format_output(output, _opts) do
{:ok, json} = JSON.encode(keys_to_atoms(output)) {:ok, json} = JSON.encode(keys_to_atoms(convert_erlang_strings(output)))
json json
end end
@ -72,4 +72,65 @@ defmodule RabbitMQ.CLI.Formatters.Json do
end end
def machine_readable?, do: true def machine_readable?, do: true
# Convert Erlang strings (lists of integers) to binaries for proper JSON encoding
# Also convert other Erlang-specific terms to readable strings
defp convert_erlang_strings(data) when is_function(data) do
"Fun()"
end
defp convert_erlang_strings(data) when is_pid(data) do
"Pid(#{inspect(data)})"
end
defp convert_erlang_strings(data) when is_port(data) do
"Port(#{inspect(data)})"
end
defp convert_erlang_strings(data) when is_reference(data) do
"Ref(#{inspect(data)})"
end
defp convert_erlang_strings(data) when is_list(data) do
# Only attempt Unicode conversion on proper lists of integers
if is_proper_list_of_integers?(data) do
case :unicode.characters_to_binary(data, :utf8) do
binary when is_binary(binary) ->
# Successfully converted - it was a valid Unicode string
binary
_ ->
# Conversion failed - not a Unicode string, process as regular list
Enum.map(data, &convert_erlang_strings/1)
end
else
# Not a proper list of integers, process as regular list
Enum.map(data, &convert_erlang_strings/1)
end
end
defp convert_erlang_strings(data) when is_tuple(data) do
data
|> Tuple.to_list()
|> Enum.map(&convert_erlang_strings/1)
|> List.to_tuple()
end
defp convert_erlang_strings(data) when is_map(data) do
Enum.into(data, %{}, fn {k, v} ->
{convert_erlang_strings(k), convert_erlang_strings(v)}
end)
end
defp convert_erlang_strings(data), do: data
# Check if data is a proper list containing only integers
defp is_proper_list_of_integers?([]), do: false # Empty lists are not strings
defp is_proper_list_of_integers?(data) when is_list(data) do
try do
Enum.all?(data, &is_integer/1)
rescue
_ -> false # Not a proper list or contains non-integers
end
end
defp is_proper_list_of_integers?(_), do: false
end end