defmodule Pi.Eval.ExceptionInfo do @moduledoc false def payload(kind, reason, stacktrace) do exception = Exception.normalize(kind, reason, stacktrace) %{ kind: inspect(kind), type: exception_type(exception), message: Exception.message(exception), stacktrace: Enum.map(stacktrace, &stacktrace_entry/1) } end defp exception_type(%module{}) when is_atom(module), do: inspect(module) defp stacktrace_entry(entry) do formatted = Exception.format_stacktrace_entry(entry) {file, line} = stacktrace_location(entry) %{ text: formatted, file: file, line: line, origin: stacktrace_origin(file, line) } end defp stacktrace_location({_module, _function, _arity_or_args, location}) when is_list(location) do {to_string(location[:file] || ""), location[:line]} end defp stacktrace_location(_), do: {"", nil} defp stacktrace_origin(file, line) when is_binary(file) and file != "" and is_integer(line) do "#{file}:#{line}" end defp stacktrace_origin(_, _), do: nil end