Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
exception.cpp
Go to the documentation of this file.
2#include <boost/exception/all.hpp>
3#include <fc/log/logger.hpp>
4#include <fc/io/json.hpp>
5
6#include <iostream>
7
8namespace fc
9{
10 FC_REGISTER_EXCEPTIONS( (timeout_exception)
11 (file_not_found_exception)
12 (parse_error_exception)
13 (invalid_arg_exception)
14 (invalid_operation_exception)
15 (key_not_found_exception)
16 (bad_cast_exception)
17 (out_of_range_exception)
18 (canceled_exception)
19 (assert_exception)
20 (eof_exception)
21 (unknown_host_exception)
22 (null_optional)
23 (udt_exception)
24 (aes_exception)
25 (overflow_exception)
27 (divide_by_zero_exception)
28 )
29
30 namespace detail
31 {
32 class exception_impl
33 {
34 public:
35 std::string _name;
36 std::string _what;
37 int64_t _code;
38 log_messages _elog;
39 };
40 }
42 const std::string& name_value,
43 const std::string& what_value )
44 :my( new detail::exception_impl() )
45 {
46 my->_code = code;
47 my->_what = what_value;
48 my->_name = name_value;
49 my->_elog = fc::move(msgs);
50 }
51
53 const log_messages& msgs,
54 int64_t code,
55 const std::string& name_value,
56 const std::string& what_value )
57 :my( new detail::exception_impl() )
58 {
59 my->_code = code;
60 my->_what = what_value;
61 my->_name = name_value;
62 my->_elog = msgs;
63 }
64
66 :exception( fc::move(m) )
67 {
68 _inner = e;
69 }
75 :exception()
76 { my->_elog = fc::move(m); }
77
78 std::exception_ptr unhandled_exception::get_inner_exception()const { return _inner; }
79
81 {
82 if( !(_inner == std::exception_ptr()) ) std::rethrow_exception( _inner );
84 }
85
86 std::shared_ptr<exception> unhandled_exception::dynamic_copy_exception()const
87 {
88 auto e = std::make_shared<unhandled_exception>( *this );
89 e->_inner = _inner;
90 return e;
91 }
92
94 const std::string& name_value,
95 const std::string& what_value )
96 :my( new detail::exception_impl() )
97 {
98 my->_code = code;
99 my->_what = what_value;
100 my->_name = name_value;
101 }
102
104 int64_t code,
105 const std::string& name_value,
106 const std::string& what_value )
107 :my( new detail::exception_impl() )
108 {
109 my->_code = code;
110 my->_what = what_value;
111 my->_name = name_value;
112 my->_elog.push_back( fc::move( msg ) );
113 }
115 :my( new detail::exception_impl(*c.my) )
116 { }
118 :my( fc::move(c.my) ){}
119
120 const char* exception::name()const throw() { return my->_name.c_str(); }
121 const char* exception::what()const noexcept { return my->_what.c_str(); }
122 int64_t exception::code()const throw() { return my->_code; }
123
125
126 void to_variant( const exception& e, variant& v )
127 {
128 v = mutable_variant_object( "code", e.code() )
129 ( "name", e.name() )
130 ( "message", e.what() )
131 ( "stack", e.get_log() );
132
133 }
134 void from_variant( const variant& v, exception& ll )
135 {
136 auto obj = v.get_object();
137 if( obj.contains( "stack" ) )
138 ll.my->_elog = obj["stack"].as<log_messages>();
139 if( obj.contains( "code" ) )
140 ll.my->_code = obj["code"].as_int64();
141 if( obj.contains( "name" ) )
142 ll.my->_name = obj["name"].as_string();
143 if( obj.contains( "message" ) )
144 ll.my->_what = obj["message"].as_string();
145 }
146
147 const log_messages& exception::get_log()const { return my->_elog; }
149 {
150 my->_elog.emplace_back( fc::move(m) );
151 }
152
159 {
160 const auto deadline = fc::time_point::now() + format_time_limit;
161 std::stringstream ss;
162 try {
163 try {
164 ss << variant( my->_code ).as_string();
165 } catch( std::bad_alloc& ) {
166 throw;
167 } catch( ... ) {
168 ss << "<- exception in to_detail_string.";
169 }
170 ss << " " << my->_name << ": " << my->_what << "\n";
171 for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ++itr ) {
172 try {
173 ss << itr->get_message() << "\n"; //fc::format_string( itr->get_format(), itr->get_data() ) <<"\n";
174 ss << " " << json::to_string( itr->get_data(), deadline ) << "\n";
175 ss << " " << itr->get_context().to_string() << "\n";
176 } catch( std::bad_alloc& ) {
177 throw;
178 } catch( const fc::timeout_exception& e) {
179 ss << "<- timeout exception in to_detail_string: " << e.what() << "\n";
180 break;
181 } catch( ... ) {
182 ss << "<- exception in to_detail_string.\n";
183 }
184 }
185 } catch( std::bad_alloc& ) {
186 throw;
187 } catch( ... ) {
188 ss << "<- exception in to_detail_string.\n";
189 }
190 return ss.str();
191 }
192
197 {
198 const auto deadline = fc::time_point::now() + format_time_limit;
199 std::stringstream ss;
200 try {
201 ss << my->_what;
202 try {
203 ss << " (" << variant( my->_code ).as_string() << ")\n";
204 } catch( std::bad_alloc& ) {
205 throw;
206 } catch( ... ) {
207 ss << "<- exception in to_string.\n";
208 }
209 for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ++itr ) {
210 try {
211 FC_CHECK_DEADLINE(deadline);
212 ss << fc::format_string( itr->get_format(), itr->get_data(), true) << "\n";
213 // ss << " " << itr->get_context().to_string() <<"\n";
214 } catch( std::bad_alloc& ) {
215 throw;
216 } catch( const fc::timeout_exception& e) {
217 ss << "<- timeout exception in to_string: " << e.what();
218 break;
219 } catch( ... ) {
220 ss << "<- exception in to_string.\n";
221 }
222 }
223 return ss.str();
224 } catch( std::bad_alloc& ) {
225 throw;
226 } catch( ... ) {
227 ss << "<- exception in to_string.\n";
228 }
229 return ss.str();
230 }
231
236 {
237 for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ++itr )
238 {
239 auto s = fc::format_string( itr->get_format(), itr->get_data() );
240 if (!s.empty()) {
241 return s;
242 }
243 }
244 return string();
245 }
246
248 {
249 auto itr = _registered_exceptions.find( e.code() );
250 if( itr != _registered_exceptions.end() )
251 itr->second->rethrow( e );
252 throw e;
253 }
263
265 {
266 return std::make_shared<exception>(*this);
267 }
268
270 {
271 return boost::current_exception_diagnostic_information();
272 }
273
274 void throw_bad_enum_cast( int64_t i, const char* e )
275 {
276 FC_THROW_EXCEPTION( bad_cast_exception,
277 "invalid index '${key}' in enum '${enum}'",
278 ("key",i)("enum",e) );
279 }
280 void throw_bad_enum_cast( const char* k, const char* e )
281 {
282 FC_THROW_EXCEPTION( bad_cast_exception,
283 "invalid name '${key}' in enum '${enum}'",
284 ("key",k)("enum",e) );
285 }
286
287 bool assert_optional(bool is_valid )
288 {
289 if( !is_valid )
290 throw null_optional();
291 return true;
292 }
294 {
295 *my = *copy.my;
296 return *this;
297 }
298
300 {
301 my = std::move(copy.my);
302 return *this;
303 }
304
306 const char* filename,
307 uint32_t lineno,
308 const char* expr
309 )
310 {
311 fc::mutable_variant_object assert_trip_info =
313 ("source_file", filename)
314 ("source_lineno", lineno)
315 ("expr", expr)
316 ;
317 /* TODO: restore this later
318 std::cout
319 << "FC_ASSERT triggered: "
320 << fc::json::to_string( assert_trip_info ) << "\n";
321 */
322 return;
323 }
324
326
328 const std::string& name_value,
329 const std::string& what_value)
330 :exception( fc::move(m), exception_code::std_exception_code, name_value, what_value )
331 {
332 _inner = {std::move(e)};
333 }
334
336 {
337 return std_exception_wrapper{FC_LOG_MESSAGE(warn, "rethrow ${what}: ", ("what",e.what())),
338 std::current_exception(),
339 BOOST_CORE_TYPEID(e).name(),
340 e.what()};
341 }
342
343 std::exception_ptr std_exception_wrapper::get_inner_exception()const { return _inner; }
344
346 {
347 if( !(_inner == std::exception_ptr()) ) std::rethrow_exception( _inner );
349 }
350
351 std::shared_ptr<exception> std_exception_wrapper::dynamic_copy_exception()const
352 {
353 auto e = std::make_shared<std_exception_wrapper>( *this );
354 e->_inner = _inner;
355 return e;
356 }
357} // fc
const mie::Vuint & r
Definition bn.cpp:28
void NO_RETURN rethrow(const exception &e) const
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
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
int64_t code() const
std::unique_ptr< detail::exception_impl > my
const char * name() const
const char * what() const noexcept override
virtual NO_RETURN void dynamic_rethrow_exception() const
std::string to_string(log_level ll=log_level::info) const
std::string top_message() const
exception & operator=(const exception &copy)
static string to_string(const variant &v, const yield_function_t &yield, const output_formatting format=output_formatting::stringify_large_ints_and_doubles)
Definition json.cpp:674
aggregates a message along with the context and associated meta-information.
An order-preserving dictionary of variants.
wrapper for std::exception
virtual std::shared_ptr< exception > dynamic_copy_exception() const
virtual NO_RETURN void dynamic_rethrow_exception() const
std::exception_ptr get_inner_exception() const
std_exception_wrapper(log_message &&m, std::exception_ptr e=std::current_exception(), const std::string &name_value="exception", const std::string &what_value="unspecified")
static std_exception_wrapper from_current_exception(const std::exception &e)
static time_point now()
Definition time.cpp:14
unhandled_exception(log_message &&m, std::exception_ptr e=std::current_exception())
Definition exception.cpp:65
virtual std::shared_ptr< exception > dynamic_copy_exception() const
Definition exception.cpp:86
virtual NO_RETURN void dynamic_rethrow_exception() const
Definition exception.cpp:80
std::exception_ptr get_inner_exception() const
Definition exception.cpp:78
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
variant_object & get_object()
Definition variant.cpp:554
string as_string() const
Definition variant.cpp:469
Defines exception's used by fc.
#define FC_CHECK_DEADLINE(DEADLINE,...)
#define FC_REGISTER_EXCEPTIONS(SEQ)
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
#define FC_LOG_MESSAGE(LOG_LEVEL, FORMAT,...)
A helper method for generating log messages.
namespace sysio::chain
Definition authority.cpp:3
std::string string
Definition string.hpp:10
std::shared_ptr< exception > exception_ptr
std::string except_str()
bool enable_record_assert_trip
void record_assert_trip(const char *filename, uint32_t lineno, const char *expr)
bool assert_optional(bool is_valid)
std::vector< log_message > log_messages
void throw_bad_enum_cast(int64_t i, const char *e)
void copy(const path &from, const path &to)
exception_code
Definition exception.hpp:18
@ std_exception_code
Definition exception.hpp:32
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
void from_variant(const fc::variant &v, sysio::chain::chain_id_type &cid)
fc::string format_string(const fc::string &, const variant_object &, bool minimize=false)
Definition variant.cpp:773
void to_variant(const sysio::chain::shared_public_key &var, fc::variant &vo)
Definition authority.cpp:4
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
#define NO_RETURN
Definition utility.hpp:15
char * s