Packages
Mishka Installer is a system plugin manager and run time installer for elixir.
Current section
Files
Jump to
Current section
Files
lib/helper/mnesia_assistant/error.ex
defmodule MishkaInstaller.Helper.MnesiaAssistant.Error do
@moduledoc """
Turns raw Mnesia results into a normalised `{:ok, :atomic}` / `{:error, error, description}` shape
and logs them.
Mnesia transactions and schema operations return `{:atomic, value}` or `{:aborted, reason}`, and
`reason` is often an atom from the documented
[error list](https://www.erlang.org/doc/man/mnesia#data-types). `error_description/2` maps those to
a human-readable description and the appropriate log level.
"""
require Logger
@error_types [
:nested_transaction,
:badarg,
:no_transaction,
:combine_error,
:bad_index,
:already_exists,
:index_exists,
:no_exists,
:system_limit,
:mnesia_down,
:not_a_db_node,
:bad_type,
:node_not_running,
:truncated_binary_file,
:active,
:illegal
]
@doc """
Returns a descriptive term for a Mnesia error. Delegates to `:mnesia.error_description/1`.
"""
@spec error_description(term()) :: term()
def error_description(error), do: :mnesia.error_description(error)
@doc """
Normalises and logs a Mnesia result for the given `identifier`.
Returns `{:ok, :atomic}` on success, or `{:error, error, description}` otherwise. Successful and
"already exists" outcomes are logged at a low level; genuine failures are logged as errors.
"""
@spec error_description(term(), term()) :: {:ok, :atomic} | {:error, term(), term()}
def error_description(error, identifier) when error in [{:atomic, :ok}, :ok] do
Logger.debug("[mishka_installer.mnesia] #{inspect(identifier)} action completed")
{:ok, :atomic}
end
def error_description(:starting, identifier) do
Logger.debug("[mishka_installer.mnesia] #{inspect(identifier)} starting")
{:ok, :atomic}
end
def error_description({:aborted, {:already_exists, _}} = error, identifier) do
already_exists(error, identifier)
end
def error_description({:error, {_, {:already_exists, _}}} = error, identifier) do
already_exists(error, identifier)
end
def error_description({:aborted, reason} = error, identifier) when is_tuple(reason) do
if elem(reason, 0) in @error_types do
converted = error_description(error)
Logger.error(
"[mishka_installer.mnesia] #{inspect(identifier)} error: #{inspect(error)} (#{inspect(converted)})"
)
{:error, error, describe(converted)}
else
generic_error(error, identifier)
end
end
def error_description(error, identifier) do
generic_error(error, identifier)
end
defp generic_error(error, identifier) do
converted = error_description(error)
Logger.error(
"[mishka_installer.mnesia] #{inspect(identifier)} error: #{inspect(error)} (#{inspect(converted)})"
)
{:error, error, converted}
end
defp already_exists(error, identifier) do
converted = error_description(error)
Logger.debug(
"[mishka_installer.mnesia] #{inspect(identifier)} already exists: #{inspect(converted)}"
)
{:error, error, describe(converted)}
end
defp describe(converted) when is_tuple(converted), do: to_string(elem(converted, 0))
defp describe(converted), do: converted
end