emoji: avoid crashing whole server on broken JSON

It may still crash due to a race condition between checking for file
existence and opening/streaming, but File.stream! has no safe version
we can use to avoid this completely.
Just not deleting such files during a reload is easy enough.
This commit is contained in:
Oneric 2025-05-17 14:14:38 +02:00
parent 5987dd43d4
commit 98762992fb
2 changed files with 20 additions and 10 deletions

View file

@ -76,9 +76,6 @@ def get_all do
:ets.tab2list(@ets)
end
@doc "Clear out old emojis"
def clear_all, do: :ets.delete_all_objects(@ets)
@doc false
def init(_) do
@ets = :ets.new(@ets, @ets_options)
@ -109,7 +106,10 @@ def code_change(_old_vsn, state, _extra) do
{:ok, state}
end
defp update_emojis([]), do: true
defp update_emojis(emojis) do
:ets.delete_all_objects(@ets)
:ets.insert(@ets, emojis)
end

View file

@ -69,7 +69,6 @@ def load do
load_pack(Path.join(emoji_dir_path, pack), emoji_groups)
end)
Emoji.clear_all()
emojis
end
@ -104,13 +103,9 @@ defp load_pack(pack_dir, emoji_groups) do
if File.exists?(pack_file) do
Logger.debug("Loading emoji pack from JSON: #{pack_file}")
contents = Jason.decode!(File.read!(pack_file))
contents["files"]
|> Enum.map(fn {name, rel_file} ->
filename = Path.join("/emoji/#{pack_name}", rel_file)
{name, filename, ["pack:#{pack_name}"]}
end)
Jason.decode(File.read!(pack_file))
|> load_from_pack(pack_name)
else
# Load from emoji.txt / all files
emoji_txt = Path.join(pack_dir, "emoji.txt")
@ -135,6 +130,21 @@ defp load_pack(pack_dir, emoji_groups) do
end
end
defp load_from_pack({:ok, %{"files" => files}}, pack_name) when is_map(files) do
Enum.map(files, fn {name, rel_file} ->
filename = Path.join("/emoji/#{pack_name}", rel_file)
{name, filename, ["pack:#{pack_name}"]}
end)
end
defp load_from_pack(pack_json_result, pack_name) do
Logger.error(
"Failed to load emoji pack #{pack_name} from pack.json:\n#{inspect(pack_json_result)}"
)
[]
end
def make_shortcode_to_file_map(pack_dir, exts) do
find_all_emoji(pack_dir, exts)
|> Enum.map(&Path.relative_to(&1, pack_dir))