首页 > 解决方案 > 引发错误时在堆栈跟踪中包含函数参数

问题描述

在 Erlang 中,当引发错误时,我可以通过将第二个参数传递给当前函数来包含参数error

-module(foo).

-export([foo/2]).

foo(A, B) ->
    error(something_went_wrong, [A, B]).

这意味着参数将在堆栈跟踪中可见,这可以使调试更容易:

> foo:foo(1, 2).
foo:foo(1, 2).
** exception error: something_went_wrong
     in function  foo:foo/2
        called as foo:foo(1,2)

在 Erlang 和 Elixir 中,这会在函数子句错误时自动发生:

defmodule Foo do
  def foo(a, b) when false do
    :ok
  end
end
> Foo.foo(1, 2)
** (FunctionClauseError) no function clause matching in Foo.foo/2    
    
    The following arguments were given to Foo.foo/2:
    
        # 1
        1
    
        # 2
        2
    
    foo.ex:2: Foo.foo/2

除了直接调用之外,有没有办法在 Elixir 中包含显式引发的异常的函数参数:erlang.error?我查看了文档Kernel.raise并没有找到任何合适的东西。

标签: elixir

解决方案


没有通用的方法可以做到这一点,因为中的异常只是一个结构。另一方面,这为您提供了灵活性,例如,在上述 中使用的FunctionClauseError定义为

defexception [:module, :function, :arity, :kind, :args, :clauses]

因此,当编译器引发它时,它message被构造为包含通过原始错误传递的参数。


为了达到同样的效果,通常使用 定义自定义异常Kernel.defexception/1,接受参数并实现两者message/1以及行为的blame/2回调Exception。一个很好的例子是实现的来源FunctionClauseError,我在上面链接。


推荐阅读