Получить трассировку стека изнутри Code.eval_quoted

Можно ли получить полную трассировку стека или посмотреть, по какой строке выдается ошибка при оценке блока в кавычках в Elixir?

Например, у меня есть этот модуль:

defmodule Test do
  def trySomeQuotedCode() do
    quote do
      IO.puts "line 1"
      IO.puts "line 2"
      5/0
    end
    |> evalMyQuoted
  end

  def evalMyQuoted(quoted) do
    Code.eval_quoted(quoted)
  end
end

Но если вы выполните его, вы увидите это:

трассировка стека до вызова

Это показывает, что был ArithmeticError с :erlang./(5, 0), что правильно, но это не показывает, где в указанном коде. С помощью этого небольшого примера все еще легко найти, где находится ошибка в коде, но если этот код в кавычках намного больше или более сложен, это может быть не так тривиально.

Итак, можно ли в этом примере получить трассировку стека, чтобы сказать, что ошибка находится на "строке 3" внутри оценки цитируемой части? Или, возможно, получить номер строки в качестве возвращаемого значения из Code.eval_quoted?

2 ответа

Решение

Вы можете определить свой quote внутри макроса, вот так:

defmodule Test do
    defmacro my_quote do
        quote do
            IO.puts "line 1"
            IO.puts "line 2"
            5/0
        end
    end

    def try_quote do
        my_quote()  # Line 11
    end
end

Сейчас звоню Test.try_quote:

iex(7)> Test.try_quote
line 1
line 2
** (ArithmeticError) bad argument in arithmetic expression
    test.exs:11: Test.try_quote/0

Таким образом, мы получаем строку, где была названа цитата, что лучше, но еще не то, что мы хотели.

Тогда решением может быть использование макроса для определения функции для нас, например:

defmodule TestMacro do
  defmacro my_quote do
    quote do
      def my_function do
        IO.puts "line 1"
        IO.puts "line 2"
        5/0 # Line 7
      end
    end
  end
end

defmodule Test do
  import TestMacro
  my_quote # Line 15
end

Сейчас звоню Test.my_function дает нам:

line 1
line 2
** (ArithmeticError) bad argument in arithmetic expression
    test.exs:15: Test.my_function/0

Который до сих пор является строкой, где был вызван макрос! Но теперь, если мы изменим определение цитаты (строка 3) на

quote location: :keep do

Мы наконец получаем точную строку, где происходит ошибка:

line 1
line 2
** (ArithmeticError) bad argument in arithmetic expression
    test.exs:7: Test.my_function/0

То, что вы ищете, это location: :keep вариант в вызове Kernel.quote/2,

Другие вопросы по тегам