盡管在 SO ( example )有類似的問題,但由于某種原因,在我的情況下錯誤以另一種方式格式化(而且我也理解 的一般含義FunctionClauseError),所以讓我再問一次。
這是我得到的問題:
{:error, reason} -> Logger.error(fn -> ["failed to fetch internal transactions for >blocks: ", inspect(reason)] end, error_count: unique_numbers_count )
給出(我添加了換行符)
2022-04-13T18:44:19.749 application=indexer fetcher=internal_transaction count=10 error_count=10 [error] 未能獲取塊的內部事務:%FunctionClauseError{args: nil, arity: 1, Clauses: nil, function: :最終確定,種類:無,模塊:EthereumJSONRPC.Geth.Tracer}
所以顯然reason是
%FunctionClauseError{args: nil, arity: 1, 子句: nil, function: :finalize, kind: nil, module: EthereumJSONRPC.Geth.Tracer}
我想知道這些位是什么意思,它們可以幫助除錯嗎?
在模塊中EthereumJSONRPC.Geth.Tracer函式finalize定義為
defp finalize(%{stack: [top], calls: [calls]}) do
傳遞給它的引數示例(導致錯誤)是:
%{
calls: [[], [], [], []],
depth: 4,
stack: [
%{
"callType" => "staticcall",
"from" => nil,
"gas" => 432013,
"gasUsed" => 21661,
"input" => "0xefc4cfa.....",
"output" => "0x",
"outputLength" => 64,
"outputOffset" => 4346,
"to" => "0x0000000000000000000000000000000000000001",
"traceAddress" => [0, 0, 0],
"type" => "call",
"value" => "0x0"
},
%{
"callType" => "staticcall",
"from" => nil,
"gas" => 438139,
"gasUsed" => 1726,
"input" => "0xefc4c.......",
"output" => "0x",
"outputLength" => 64,
"outputOffset" => 4026,
"to" => "0x0000000000000000000000000000000000000001",
"traceAddress" => [0, 0],
"type" => "call",
"value" => "0x0"
},
%{
"callType" => "staticcall",
"from" => nil
"gas" => 445060,
"gasUsed" => 2521,
"input" => "0xefc4......",
"output" => "0x",
"outputLength" => 64,
"outputOffset" => 3706,
"to" => "0x0000000000000000000000000000000000000001",
"traceAddress" => [0],
"type" => "call",
"value" => "0x0"
},
%{
"callType" => "call",
"from" => "0x9a66644084108a1bc23a9ccd50d6d63e53098db6",
"gas" => 460960,
"gasUsed" => 11500,
"input" => "0xba2c.........",
"output" => "0x",
"to" => "0x841ce48f9446c8e281d3f1444cb859b4a6d0738c",
"traceAddress" => [],
"type" => "call",
"value" => "0x0"
}
],
trace_address: [0, 0, 0, 0]
}
這對我來說看起來不錯(它同時具有stack和calls道具)。我可以從該args: nil, arity: 1, clauses: nil, function: :finalize, kind: nil位中提取更多內容以進行除錯嗎?如果您指出原因,它也會有所幫助,但我也想了解如何除錯它。額外的道具 ( depth, trace_address) 會成為問題的根源嗎?finalize或者我應該在函式體內尋找錯誤原因?(據我了解,沒有)
PS給尋求除錯幫助的其他人的說明:錯誤文本之前的位
application=indexer fetcher=internal_transaction count=10 error_count=10
可能包含有用的資訊:如果您查找Logger.metadata,您可能會發現類似
Logger.metadata(fetcher: :internal_transaction)
這可以提示錯誤的來源。
uj5u.com熱心網友回復:
旁注: @sabiwara 提供的答案有很多有用的資訊,應該標記為正確的。
這是您收到錯誤的原因:
defp finalize(%{stack: [top], calls: [calls]})
這定義了一個函式,接受一個帶有鍵的映射,包括但不限于:stackand :calls,它們的值是只包含一個元素的串列。
您在那里傳遞更長的串列,因此出現錯誤。這可能是您想要做的:
defp finalize(%{stack: top, calls: calls})
when is_list(top) and is_list(calls)
uj5u.com熱心網友回復:
默認情況下,如果您不使用try / rescue, aFunctionClauseError將記錄除錯它所需的所有資訊(值、模式、堆疊跟蹤):
> String.downcase(1)
** (FunctionClauseError) no function clause matching in String.downcase/2
The following arguments were given to String.downcase/2:
# 1
1
# 2
:default
...
但是,如果您修復錯誤并將其作為元組回傳,您將丟失大部分資訊:
try do
String.downcase(1)
rescue
err -> {:error, err}
end
結果將只包含一個非常簡單的結構:
{:error,
%FunctionClauseError{
args: nil,
arity: 2,
clauses: nil,
function: :downcase,
kind: nil,
module: String
}}
您可以使用本官方指南中解釋的方法直接登錄救援條款,如果__STACKTRACE__可用:
try do
String.downcase(1)
rescue
err ->
# format the exception in a readable way
Exception.format(:error, err, __STACKTRACE__)
|> Logger.error()
# return value
:error
end
話雖如此,這在 Elixir 中并不常見,try/rescue正如上面指南中所解釋的那樣。大多數時候,你只是讓意想不到的事情失敗(著名的“讓它崩潰”的哲學),并將:error元組用于你真正期望和想要處理的情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/460884.html
上一篇:JS頁面加載除錯
