elixir - 引发错误时在堆栈跟踪中包含函数参数
问题描述
在 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
,我在上面链接。