FC Updates from BitShares and myself #21
4 changed files with 104 additions and 38 deletions
|
|
@ -159,5 +159,7 @@ FC_REFLECT_TYPENAME( fc::log_message );
|
||||||
* @param ... A set of key/value pairs denoted as ("key",val)("key2",val2)...
|
* @param ... A set of key/value pairs denoted as ("key",val)("key2",val2)...
|
||||||
*/
|
*/
|
||||||
#define FC_LOG_MESSAGE( LOG_LEVEL, FORMAT, ... ) \
|
#define FC_LOG_MESSAGE( LOG_LEVEL, FORMAT, ... ) \
|
||||||
fc::log_message( FC_LOG_CONTEXT(LOG_LEVEL), FORMAT, fc::limited_mutable_variant_object(FC_MAX_LOG_OBJECT_DEPTH)__VA_ARGS__ )
|
fc::log_message( FC_LOG_CONTEXT(LOG_LEVEL), \
|
||||||
|
FORMAT, \
|
||||||
|
fc::limited_mutable_variant_object( FC_MAX_LOG_OBJECT_DEPTH, true )__VA_ARGS__ )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,12 +156,39 @@ namespace fc
|
||||||
#define FC_FORMAT_ARG_PARAMS( ... )\
|
#define FC_FORMAT_ARG_PARAMS( ... )\
|
||||||
BOOST_PP_SEQ_FOR_EACH( FC_FORMAT_ARGS, v, __VA_ARGS__ )
|
BOOST_PP_SEQ_FOR_EACH( FC_FORMAT_ARGS, v, __VA_ARGS__ )
|
||||||
|
|
||||||
|
#define FC_DUMP_FORMAT_ARG_NAME(r, unused, base) \
|
||||||
|
"(" BOOST_PP_STRINGIZE(base) ")"
|
||||||
|
|
||||||
|
#define FC_DUMP_FORMAT_ARG_NAMES( SEQ )\
|
||||||
|
BOOST_PP_SEQ_FOR_EACH( FC_DUMP_FORMAT_ARG_NAME, v, SEQ )
|
||||||
|
|
||||||
|
// TODO FC_FORMAT_ARG_PARAMS(...) may throw exceptions when calling fc::variant(...) inside,
|
||||||
|
// as a quick-fix / workaround, we catch all exceptions here.
|
||||||
|
// However, to log as much info as possible, it's better to catch exceptions when processing each argument
|
||||||
#define idump( SEQ ) \
|
#define idump( SEQ ) \
|
||||||
ilog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
{ \
|
||||||
|
try { \
|
||||||
|
ilog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) ); \
|
||||||
|
} catch( ... ) { \
|
||||||
|
ilog ( "[ERROR: Got exception while trying to dump ( ${args} )]",("args",FC_DUMP_FORMAT_ARG_NAMES(SEQ)) ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
#define wdump( SEQ ) \
|
#define wdump( SEQ ) \
|
||||||
wlog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
{ \
|
||||||
|
try { \
|
||||||
|
wlog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) ); \
|
||||||
|
} catch( ... ) { \
|
||||||
|
wlog ( "[ERROR: Got exception while trying to dump ( ${args} )]",("args",FC_DUMP_FORMAT_ARG_NAMES(SEQ)) ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
#define edump( SEQ ) \
|
#define edump( SEQ ) \
|
||||||
elog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
{ \
|
||||||
|
try { \
|
||||||
|
elog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) ); \
|
||||||
|
} catch( ... ) { \
|
||||||
|
elog ( "[ERROR: Got exception while trying to dump ( ${args} )]",("args",FC_DUMP_FORMAT_ARG_NAMES(SEQ)) ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
// this disables all normal logging statements -- not something you'd normally want to do,
|
// this disables all normal logging statements -- not something you'd normally want to do,
|
||||||
// but it's useful if you're benchmarking something and suspect logging is causing
|
// but it's useful if you're benchmarking something and suspect logging is causing
|
||||||
|
|
|
||||||
|
|
@ -221,18 +221,35 @@ namespace fc
|
||||||
class limited_mutable_variant_object : public mutable_variant_object
|
class limited_mutable_variant_object : public mutable_variant_object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
limited_mutable_variant_object( uint32_t max_depth );
|
limited_mutable_variant_object( uint32_t max_depth, bool skip_on_exception = false );
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
limited_mutable_variant_object& operator()( string key, T&& var )
|
limited_mutable_variant_object& operator()( string key, T&& var )
|
||||||
{
|
{
|
||||||
set( std::move(key), variant( fc::forward<T>(var), _max_depth ) );
|
if( _reached_depth_limit )
|
||||||
|
// _skip_on_exception will always be true here
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
optional<variant> v;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
v = variant( fc::forward<T>(var), _max_depth );
|
||||||
|
}
|
||||||
|
catch( ... )
|
||||||
|
{
|
||||||
|
if( !_skip_on_exception )
|
||||||
|
throw;
|
||||||
|
v = variant( "[ERROR: Caught exception while converting data to variant]" );
|
||||||
|
}
|
||||||
|
set( std::move(key), *v );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
limited_mutable_variant_object& operator()( const variant_object& vo );
|
limited_mutable_variant_object& operator()( const variant_object& vo );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const uint32_t _max_depth;
|
const uint32_t _max_depth; ///< The depth limit
|
||||||
|
const bool _reached_depth_limit; ///< Indicates whether we've reached depth limit
|
||||||
|
const bool _skip_on_exception; ///< If set to true, won't rethrow exceptions when reached depth limit
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @ingroup Serializable */
|
/** @ingroup Serializable */
|
||||||
|
|
|
||||||
|
|
@ -365,15 +365,35 @@ namespace fc
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
limited_mutable_variant_object::limited_mutable_variant_object( uint32_t m )
|
limited_mutable_variant_object::limited_mutable_variant_object( uint32_t m, bool skip_on_exception )
|
||||||
: mutable_variant_object(), _max_depth(m - 1)
|
: mutable_variant_object(),
|
||||||
|
_max_depth(m - 1),
|
||||||
|
_reached_depth_limit(m == 0),
|
||||||
|
_skip_on_exception(skip_on_exception)
|
||||||
{
|
{
|
||||||
|
if( !skip_on_exception )
|
||||||
FC_ASSERT( m > 0, "Recursion depth exceeded!" );
|
FC_ASSERT( m > 0, "Recursion depth exceeded!" );
|
||||||
|
else if( m == 0 )
|
||||||
|
set( "__err_msg", "[ERROR: Recusion depth exceeded!]" );
|
||||||
}
|
}
|
||||||
|
|
||||||
limited_mutable_variant_object& limited_mutable_variant_object::operator()( const variant_object& vo )
|
limited_mutable_variant_object& limited_mutable_variant_object::operator()( const variant_object& vo )
|
||||||
|
{
|
||||||
|
if( _reached_depth_limit )
|
||||||
|
// _skip_on_exception will always be true here
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
mutable_variant_object::operator()( vo );
|
mutable_variant_object::operator()( vo );
|
||||||
|
}
|
||||||
|
catch( ... )
|
||||||
|
{
|
||||||
|
if( !_skip_on_exception )
|
||||||
|
throw;
|
||||||
|
else
|
||||||
|
set( "__err_msg", "[ERROR: Caught exception in operator()( const variant_object& ).]" );
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue