eos的异常机制基于 eos/libraries/fc/include/fc/exception已有的异常机制,eos自身派生出来的异常实现在eos/libraries/chain/exceptions.hpp。下面讲几个关于异常的宏
- 异常抛出
1)EOS_THROW
例如 EOS_THROW(chain::wallet_missing_pub_key_exception, "Public key not found in unlocked wallets {k}", fc::mutable_variant_object()("k", pk) ) );
2)EOS_ASSERT
例如 EOS_ASSERT(!wallets.empty(), wallet_not_available_exception, "You don't have any wallet!");
这个宏展开之后
do
{
if( !(!wallets.empty()) )
do
{
throw wallet_not_available_exception( fc::log_message( fc::log_context( fc::log_level::error, "wallet_manager.cpp", 137, FUNCTION ), "You don't have any wallet!", fc::mutable_variant_object() ) );
} while (0);
} while (0);
- 异常捕获
FC_CAPTURE_AND_RETHROW,FC_RETHROW_EXCEPTIONS,这2个异常捕获宏都是捕获异常之后添加异常信息再throw,最终在命令行中显示出来的信息按照异常throw的先后顺序打印,最顶端是最开始抛出异常的地方,后面是捕获异常之后添加异常信息的顺序打印,例如 下面在命令行显示的异常信息
// 最先抛的异常 可以看成这是一个assert抛出的异常 显示账号不存在
assertion failure with message: to account does not exist
{"s":"to account does not exist"}
thread-0 wasm_interface.cpp:930 eosio_assert // 抛出异常的代码位置
// FC_RETHROW_EXCEPTIONS添加的异常信息 这里它先添加action执行过程中添加的console信息
pending console output:
{"console":""}
thread-0 apply_context.cpp:65 exec_one // 抛出异常的代码位置
- 最终捕获
最终通过catch捕获之后xlog(可以输出到std_out,std_error或者日志文件中去,当然可以在命令中把nodeos的输入输出重定向到一个文件)