【问题标题】:Get stacktrace from inside Code.eval_quoted从 Code.eval_quoted 内部获取堆栈跟踪
【发布时间】:2018-11-24 16:50:52
【问题描述】:

在 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 获取行号作为返回值?

【问题讨论】:

    标签: elixir stack-trace


    【解决方案1】:

    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”确实是我要找的东西!谢谢
    【解决方案2】:

    您正在寻找的是对Kernel.quote/2 的调用中的location: :keep 选项。

    【讨论】:

    • Gabriel Prá 也已经回答了“location::keep”,但您提供的链接也很有帮助!
    猜你喜欢
    • 2010-10-11
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 2018-07-19
    • 2011-06-15
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多