Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
exception.hpp
Go to the documentation of this file.
1#pragma once
6#include <fc/log/logger.hpp>
7#include <exception>
8#include <functional>
9#include <unordered_map>
10#include <boost/core/typeinfo.hpp>
11#include <boost/interprocess/exceptions.hpp>
12
13namespace fc
14{
15 namespace detail { class exception_impl; }
16
42
57 class exception : public std::exception
58 {
59 public:
60 static constexpr fc::microseconds format_time_limit = fc::milliseconds( 10 ); // limit time spent formatting exceptions
61
66
68 const std::string& name_value = "exception",
69 const std::string& what_value = "unspecified");
71 const std::string& name_value = "exception",
72 const std::string& what_value = "unspecified");
74 const std::string& name_value = "exception",
75 const std::string& what_value = "unspecified");
76 exception( const log_messages&,
78 const std::string& name_value = "exception",
79 const std::string& what_value = "unspecified");
80 exception( const exception& e );
81 exception( exception&& e );
82 virtual ~exception();
83
84 const char* name()const throw();
85 int64_t code()const throw();
86 const char* what()const noexcept override;
87
92 const log_messages& get_log()const;
93 void append_log( log_message m );
94
100 std::string to_detail_string( log_level ll = log_level::all )const;
101
105 std::string to_string( log_level ll = log_level::info )const;
106
110 std::string top_message( )const;
111
117 virtual NO_RETURN void dynamic_rethrow_exception()const;
118
126 virtual std::shared_ptr<exception> dynamic_copy_exception()const;
127
128 friend void to_variant( const exception& e, variant& v );
129 friend void from_variant( const variant& e, exception& ll );
130
131 exception& operator=( const exception& copy );
132 exception& operator=( exception&& copy );
133 protected:
134 std::unique_ptr<detail::exception_impl> my;
135 };
136
137 void to_variant( const exception& e, variant& v );
138 void from_variant( const variant& e, exception& ll );
139 typedef std::shared_ptr<exception> exception_ptr;
140
141 typedef std::optional<exception> oexception;
142
143
155 {
156 public:
160 unhandled_exception( log_message&& m, std::exception_ptr e = std::current_exception() );
163
164 std::exception_ptr get_inner_exception()const;
165
166 virtual NO_RETURN void dynamic_rethrow_exception()const;
167 virtual std::shared_ptr<exception> dynamic_copy_exception()const;
168 private:
169 std::exception_ptr _inner;
170 };
171
180 {
181 public:
183 std::exception_ptr e = std::current_exception(),
184 const std::string& name_value = "exception",
185 const std::string& what_value = "unspecified");
186
187 std::exception_ptr get_inner_exception()const;
188
189 static std_exception_wrapper from_current_exception(const std::exception& e);
190
191 virtual NO_RETURN void dynamic_rethrow_exception()const;
192 virtual std::shared_ptr<exception> dynamic_copy_exception()const;
193 private:
194 std::exception_ptr _inner;
195 };
196
197 template<typename T>
199 {
200#if defined(_MSC_VER) && (_MSC_VER < 1700)
201 return std::make_shared<unhandled_exception>( log_message(),
202 std::copy_exception(fc::forward<T>(e)) );
203#else
204 return std::make_shared<unhandled_exception>( log_message(),
205 std::make_exception_ptr(fc::forward<T>(e)) );
206#endif
207 }
208
209
211 {
212 public:
214 {
215 virtual NO_RETURN void rethrow( const exception& e )const = 0;
216 };
217
218 template<typename T>
220 {
221 virtual NO_RETURN void rethrow( const exception& e )const override
222 {
223 throw T( e );
224 }
225 };
226
227 template<typename T>
229 {
230 static exception_builder<T> builder;
231 auto itr = _registered_exceptions.find( T::code_value );
232 assert( itr == _registered_exceptions.end() );
233 (void)itr; // in release builds this hides warnings
234 _registered_exceptions[T::code_value] = &builder;
235 }
236
237 void NO_RETURN rethrow( const exception& e )const;
238
240 {
241 static exception_factory once;
242 return once;
243 }
244
245 private:
246 std::unordered_map<int64_t,base_exception_builder*> _registered_exceptions;
247 };
248#define FC_REGISTER_EXCEPTION(r, unused, base) \
249 fc::exception_factory::instance().register_exception<base>();
250
251#define FC_REGISTER_EXCEPTIONS( SEQ )\
252 \
253 static bool exception_init = []()->bool{ \
254 BOOST_PP_SEQ_FOR_EACH( FC_REGISTER_EXCEPTION, v, SEQ ) \
255 return true; \
256 }(); \
257
258
259#define FC_DECLARE_DERIVED_EXCEPTION( TYPE, BASE, CODE, WHAT ) \
260 class TYPE : public BASE \
261 { \
262 public: \
263 enum code_enum { \
264 code_value = CODE, \
265 }; \
266 explicit TYPE( int64_t code, const std::string& name_value, const std::string& what_value ) \
267 :BASE( code, name_value, what_value ){} \
268 explicit TYPE( fc::log_message&& m, int64_t code, const std::string& name_value, const std::string& what_value ) \
269 :BASE( std::move(m), code, name_value, what_value ){} \
270 explicit TYPE( fc::log_messages&& m, int64_t code, const std::string& name_value, const std::string& what_value )\
271 :BASE( std::move(m), code, name_value, what_value ){}\
272 explicit TYPE( const fc::log_messages& m, int64_t code, const std::string& name_value, const std::string& what_value )\
273 :BASE( m, code, name_value, what_value ){}\
274 TYPE( const std::string& what_value, const fc::log_messages& m ) \
275 :BASE( m, CODE, BOOST_PP_STRINGIZE(TYPE), what_value ){} \
276 TYPE( fc::log_message&& m ) \
277 :BASE( fc::move(m), CODE, BOOST_PP_STRINGIZE(TYPE), WHAT ){}\
278 TYPE( fc::log_messages msgs ) \
279 :BASE( fc::move( msgs ), CODE, BOOST_PP_STRINGIZE(TYPE), WHAT ) {} \
280 TYPE( const TYPE& c ) \
281 :BASE(c){} \
282 TYPE( const BASE& c ) \
283 :BASE(c){} \
284 TYPE():BASE(CODE, BOOST_PP_STRINGIZE(TYPE), WHAT){}\
285 \
286 virtual std::shared_ptr<fc::exception> dynamic_copy_exception()const\
287 { return std::make_shared<TYPE>( *this ); } \
288 virtual NO_RETURN void dynamic_rethrow_exception()const \
289 { if( code() == CODE ) throw *this;\
290 else fc::exception::dynamic_rethrow_exception(); \
291 } \
292 };
293
294 #define FC_DECLARE_EXCEPTION( TYPE, CODE, WHAT ) \
295 FC_DECLARE_DERIVED_EXCEPTION( TYPE, fc::exception, CODE, WHAT )
296
297 FC_DECLARE_EXCEPTION( timeout_exception, timeout_exception_code, "Timeout" );
298 FC_DECLARE_EXCEPTION( file_not_found_exception, file_not_found_exception_code, "File Not Found" );
302 FC_DECLARE_EXCEPTION( parse_error_exception, parse_error_exception_code, "Parse Error" );
303 FC_DECLARE_EXCEPTION( invalid_arg_exception, invalid_arg_exception_code, "Invalid Argument" );
307 FC_DECLARE_EXCEPTION( key_not_found_exception, key_not_found_exception_code, "Key Not Found" );
308 FC_DECLARE_EXCEPTION( bad_cast_exception, bad_cast_exception_code, "Bad Cast" );
309 FC_DECLARE_EXCEPTION( out_of_range_exception, out_of_range_exception_code, "Out of Range" );
310
312 FC_DECLARE_EXCEPTION( invalid_operation_exception,
314 "Invalid Operation" );
316 FC_DECLARE_EXCEPTION( unknown_host_exception,
318 "Unknown Host" );
319
323 FC_DECLARE_EXCEPTION( canceled_exception, canceled_exception_code, "Canceled" );
327 FC_DECLARE_EXCEPTION( assert_exception, assert_exception_code, "Assert Exception" );
328 FC_DECLARE_EXCEPTION( eof_exception, eof_exception_code, "End Of File" );
329 FC_DECLARE_EXCEPTION( null_optional, null_optional_code, "null optional" );
330 FC_DECLARE_EXCEPTION( udt_exception, udt_error_code, "UDT error" );
331 FC_DECLARE_EXCEPTION( aes_exception, aes_error_code, "AES error" );
332 FC_DECLARE_EXCEPTION( overflow_exception, overflow_code, "Integer Overflow" );
334 FC_DECLARE_EXCEPTION( divide_by_zero_exception, divide_by_zero_code, "Integer Divide By Zero" );
335
336 std::string except_str();
337
339 const char* filename,
340 uint32_t lineno,
341 const char* expr
342 );
343
344 extern bool enable_record_assert_trip;
345} // namespace fc
346
347#if __APPLE__
348 #define LIKELY(x) __builtin_expect((long)!!(x), 1L)
349 #define UNLIKELY(x) __builtin_expect((long)!!(x), 0L)
350#else
351 #define LIKELY(x) (x)
352 #define UNLIKELY(x) (x)
353#endif
354
358#define FC_EXPAND_MACRO( x ) x
362#define FC_ASSERT( TEST, ... ) \
363 FC_EXPAND_MACRO( \
364 FC_MULTILINE_MACRO_BEGIN \
365 if( UNLIKELY(!(TEST)) ) \
366 { \
367 if( fc::enable_record_assert_trip ) \
368 fc::record_assert_trip( __FILE__, __LINE__, #TEST ); \
369 FC_THROW_EXCEPTION( fc::assert_exception, #TEST ": " __VA_ARGS__ ); \
370 } \
371 FC_MULTILINE_MACRO_END \
372 )
373
374#define FC_CAPTURE_AND_THROW( EXCEPTION_TYPE, ... ) \
375 FC_MULTILINE_MACRO_BEGIN \
376 throw EXCEPTION_TYPE( FC_LOG_MESSAGE( error, "", FC_FORMAT_ARG_PARAMS(__VA_ARGS__) ) ); \
377 FC_MULTILINE_MACRO_END
378
379//#define FC_THROW( FORMAT, ... )
380// FC_INDIRECT_EXPAND workas around a bug in Visual C++ variadic macro processing that prevents it
381// from separating __VA_ARGS__ into separate tokens
382#define FC_INDIRECT_EXPAND(MACRO, ARGS) MACRO ARGS
383#define FC_THROW( ... ) \
384 FC_MULTILINE_MACRO_BEGIN \
385 throw fc::exception( FC_INDIRECT_EXPAND(FC_LOG_MESSAGE, ( error, __VA_ARGS__ )) ); \
386 FC_MULTILINE_MACRO_END
387
388#define FC_EXCEPTION( EXCEPTION_TYPE, FORMAT, ... ) \
389 EXCEPTION_TYPE( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) )
395#define FC_THROW_EXCEPTION( EXCEPTION, FORMAT, ... ) \
396 FC_MULTILINE_MACRO_BEGIN \
397 throw EXCEPTION( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
398 FC_MULTILINE_MACRO_END
399
400
405#define FC_RETHROW_EXCEPTION( ER, LOG_LEVEL, FORMAT, ... ) \
406 FC_MULTILINE_MACRO_BEGIN \
407 ER.append_log( FC_LOG_MESSAGE( LOG_LEVEL, FORMAT, __VA_ARGS__ ) ); \
408 throw; \
409 FC_MULTILINE_MACRO_END
410
411#define FC_LOG_AND_RETHROW( ) \
412 catch( const boost::interprocess::bad_alloc& ) {\
413 throw;\
414 } catch( fc::exception& er ) { \
415 wlog( "${details}", ("details",er.to_detail_string()) ); \
416 FC_RETHROW_EXCEPTION( er, warn, "rethrow" ); \
417 } catch( const std::exception& e ) { \
418 fc::std_exception_wrapper sew( \
419 FC_LOG_MESSAGE( warn, "rethrow ${what}: ", ("what",e.what())), \
420 std::current_exception(), \
421 BOOST_CORE_TYPEID(e).name(), \
422 e.what() ) ; \
423 wlog( "${details}", ("details",sew.to_detail_string()) ); \
424 throw sew;\
425 } catch( ... ) { \
426 fc::unhandled_exception e( \
427 FC_LOG_MESSAGE( warn, "rethrow"), \
428 std::current_exception() ); \
429 wlog( "${details}", ("details",e.to_detail_string()) ); \
430 throw e; \
431 }
432
433#define FC_CAPTURE_LOG_AND_RETHROW( ... ) \
434 catch( const boost::interprocess::bad_alloc& ) {\
435 throw;\
436 } catch( fc::exception& er ) { \
437 wlog( "${details}", ("details",er.to_detail_string()) ); \
438 wdump( __VA_ARGS__ ); \
439 FC_RETHROW_EXCEPTION( er, warn, "rethrow", FC_FORMAT_ARG_PARAMS(__VA_ARGS__) ); \
440 } catch( const std::exception& e ) { \
441 fc::std_exception_wrapper sew( \
442 FC_LOG_MESSAGE( warn, "rethrow ${what}: ", FC_FORMAT_ARG_PARAMS( __VA_ARGS__ )("what",e.what())), \
443 std::current_exception(), \
444 BOOST_CORE_TYPEID(e).name(), \
445 e.what() ) ; \
446 wlog( "${details}", ("details",sew.to_detail_string()) ); \
447 wdump( __VA_ARGS__ ); \
448 throw sew;\
449 } catch( ... ) { \
450 fc::unhandled_exception e( \
451 FC_LOG_MESSAGE( warn, "rethrow", FC_FORMAT_ARG_PARAMS( __VA_ARGS__) ), \
452 std::current_exception() ); \
453 wlog( "${details}", ("details",e.to_detail_string()) ); \
454 wdump( __VA_ARGS__ ); \
455 throw e; \
456 }
457
458#define FC_CAPTURE_AND_LOG( ... ) \
459 catch( const boost::interprocess::bad_alloc& ) {\
460 throw;\
461 } catch( fc::exception& er ) { \
462 wlog( "${details}", ("details",er.to_detail_string()) ); \
463 wdump( __VA_ARGS__ ); \
464 } catch( const std::exception& e ) { \
465 fc::std_exception_wrapper sew( \
466 FC_LOG_MESSAGE( warn, "rethrow ${what}: ",FC_FORMAT_ARG_PARAMS( __VA_ARGS__ )("what",e.what()) ), \
467 std::current_exception(), \
468 BOOST_CORE_TYPEID(e).name(), \
469 e.what() ) ; \
470 wlog( "${details}", ("details",sew.to_detail_string()) ); \
471 wdump( __VA_ARGS__ ); \
472 } catch( ... ) { \
473 fc::unhandled_exception e( \
474 FC_LOG_MESSAGE( warn, "rethrow", FC_FORMAT_ARG_PARAMS( __VA_ARGS__) ), \
475 std::current_exception() ); \
476 wlog( "${details}", ("details",e.to_detail_string()) ); \
477 wdump( __VA_ARGS__ ); \
478 }
479
480#define FC_LOG_AND_DROP( ... ) \
481 catch( const boost::interprocess::bad_alloc& ) {\
482 throw;\
483 } catch( fc::exception& er ) { \
484 wlog( "${details}", ("details",er.to_detail_string()) ); \
485 } catch( const std::exception& e ) { \
486 fc::std_exception_wrapper sew( \
487 FC_LOG_MESSAGE( warn, "rethrow ${what}: ",FC_FORMAT_ARG_PARAMS( __VA_ARGS__ )("what",e.what()) ), \
488 std::current_exception(), \
489 BOOST_CORE_TYPEID(e).name(), \
490 e.what() ) ; \
491 wlog( "${details}", ("details",sew.to_detail_string()) ); \
492 } catch( ... ) { \
493 fc::unhandled_exception e( \
494 FC_LOG_MESSAGE( warn, "rethrow", FC_FORMAT_ARG_PARAMS( __VA_ARGS__) ), \
495 std::current_exception() ); \
496 wlog( "${details}", ("details",e.to_detail_string()) ); \
497 }
498
499
505#define FC_RETHROW_EXCEPTIONS( LOG_LEVEL, FORMAT, ... ) \
506 catch( const boost::interprocess::bad_alloc& ) {\
507 throw;\
508 } catch( fc::exception& er ) { \
509 FC_RETHROW_EXCEPTION( er, LOG_LEVEL, FORMAT, __VA_ARGS__ ); \
510 } catch( const std::exception& e ) { \
511 fc::std_exception_wrapper sew( \
512 FC_LOG_MESSAGE( LOG_LEVEL, "${what}: " FORMAT,__VA_ARGS__("what",e.what())), \
513 std::current_exception(), \
514 BOOST_CORE_TYPEID(e).name(), \
515 e.what() ); \
516 throw sew;\
517 } catch( ... ) { \
518 throw fc::unhandled_exception( \
519 FC_LOG_MESSAGE( LOG_LEVEL, FORMAT,__VA_ARGS__), \
520 std::current_exception() ); \
521 }
522
523#define FC_CAPTURE_AND_RETHROW( ... ) \
524 catch( const boost::interprocess::bad_alloc& ) {\
525 throw;\
526 } catch( fc::exception& er ) { \
527 FC_RETHROW_EXCEPTION( er, warn, "", FC_FORMAT_ARG_PARAMS(__VA_ARGS__) ); \
528 } catch( const std::exception& e ) { \
529 fc::std_exception_wrapper sew( \
530 FC_LOG_MESSAGE( warn, "${what}: ",FC_FORMAT_ARG_PARAMS(__VA_ARGS__)("what",e.what())), \
531 std::current_exception(), \
532 BOOST_CORE_TYPEID(e).name(), \
533 e.what() ); \
534 throw sew;\
535 } catch( ... ) { \
536 throw fc::unhandled_exception( \
537 FC_LOG_MESSAGE( warn, "",FC_FORMAT_ARG_PARAMS(__VA_ARGS__)), \
538 std::current_exception() ); \
539 }
540
541#define FC_CHECK_DEADLINE( DEADLINE, ... ) \
542 FC_MULTILINE_MACRO_BEGIN \
543 if( DEADLINE < fc::time_point::maximum() && DEADLINE < fc::time_point::now() ) { \
544 auto log_mgs = FC_LOG_MESSAGE( error, "deadline ${d} exceeded by ${t}us ", \
545 FC_FORMAT_ARG_PARAMS(__VA_ARGS__)("d", DEADLINE)("t", fc::time_point::now() - DEADLINE) ); \
546 auto msg = log_mgs.get_limited_message(); \
547 throw fc::timeout_exception( std::move( log_mgs ), fc::timeout_exception_code, "timeout_exception", std::move( msg ) ); \
548 } \
549 FC_MULTILINE_MACRO_END
static exception_factory & instance()
Used to generate a useful error report when an exception is thrown.
Definition exception.hpp:58
static constexpr fc::microseconds format_time_limit
Definition exception.hpp:60
virtual std::shared_ptr< exception > dynamic_copy_exception() const
friend void to_variant(const exception &e, variant &v)
exception(int64_t code=unspecified_exception_code, const std::string &name_value="exception", const std::string &what_value="unspecified")
Definition exception.cpp:93
void append_log(log_message m)
const log_messages & get_log() const
virtual ~exception()
std::string to_detail_string(log_level ll=log_level::all) const
std::unique_ptr< detail::exception_impl > my
friend void from_variant(const variant &e, exception &ll)
const char * name() const
const char * what() const noexcept override
virtual NO_RETURN void dynamic_rethrow_exception() const
std::string top_message() const
aggregates a message along with the context and associated meta-information.
wrapper for std::exception
re-thrown whenever an unhandled exception is caught.Any exceptions thrown by 3rd party libraries that...
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
#define FC_DECLARE_EXCEPTION(TYPE, CODE, WHAT)
namespace sysio::chain
Definition authority.cpp:3
std::shared_ptr< exception > exception_ptr
fc::exception_ptr copy_exception(T &&e)
std::string except_str()
bool enable_record_assert_trip
void record_assert_trip(const char *filename, uint32_t lineno, const char *expr)
std::vector< log_message > log_messages
constexpr microseconds milliseconds(int64_t s)
Definition time.hpp:33
void copy(const path &from, const path &to)
exception_code
Definition exception.hpp:18
@ timeout_exception_code
timeout exceptions
Definition exception.hpp:22
@ unknown_host_exception_code
Definition exception.hpp:34
@ assert_exception_code
Definition exception.hpp:30
@ bad_cast_exception_code
Definition exception.hpp:27
@ unhandled_exception_code
for unhandled 3rd party exceptions
Definition exception.hpp:21
@ udt_error_code
Definition exception.hpp:36
@ aes_error_code
Definition exception.hpp:37
@ divide_by_zero_code
Definition exception.hpp:40
@ file_not_found_exception_code
Definition exception.hpp:23
@ unspecified_exception_code
Definition exception.hpp:20
@ null_optional_code
Definition exception.hpp:35
@ parse_error_exception_code
Definition exception.hpp:24
@ invalid_arg_exception_code
Definition exception.hpp:25
@ key_not_found_exception_code
Definition exception.hpp:26
@ std_exception_code
Definition exception.hpp:32
@ canceled_exception_code
Definition exception.hpp:29
@ eof_exception_code
Definition exception.hpp:31
@ invalid_operation_exception_code
Definition exception.hpp:33
@ out_of_range_exception_code
Definition exception.hpp:28
@ overflow_code
Definition exception.hpp:38
@ underflow_code
Definition exception.hpp:39
file_not_found_exception parse_error_exception invalid_arg_exception invalid_operation_exception key_not_found_exception bad_cast_exception out_of_range_exception canceled_exception assert_exception eof_exception unknown_host_exception null_optional udt_exception aes_exception overflow_exception underflow_exception(divide_by_zero_exception)) namespace detail
Definition exception.cpp:27
std::optional< exception > oexception
Definition name.hpp:106
#define T(meth, val, expected)
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
virtual NO_RETURN void rethrow(const exception &e) const =0
virtual NO_RETURN void rethrow(const exception &e) const override
#define NO_RETURN
Definition utility.hpp:15
struct @108 class