从内部获取堆栈跟踪 Code.eval_quoted
Get stacktrace from inside 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)
,这是正确的,但它没有显示引用代码中的位置。通过这个小例子,仍然很容易找到代码中的错误所在,但是如果这个引用的代码更大或更高级,它可能不会那么微不足道。
那么,对于这个例子,是否有可能让堆栈跟踪表明在引用部分的评估中错误出现在 "line 3" 上?或者从 Code.eval_quoted
?
中获取行号作为 return 值
TLDR: 使用 location: :keep.
您可以在宏中定义 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
option in the call to Kernel.quote/2
。
在 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)
,这是正确的,但它没有显示引用代码中的位置。通过这个小例子,仍然很容易找到代码中的错误所在,但是如果这个引用的代码更大或更高级,它可能不会那么微不足道。
那么,对于这个例子,是否有可能让堆栈跟踪表明在引用部分的评估中错误出现在 "line 3" 上?或者从 Code.eval_quoted
?
TLDR: 使用 location: :keep.
您可以在宏中定义 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
option in the call to Kernel.quote/2
。