Получить трассировку стека изнутри 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
,