13
13
#include " buffer_info.h"
14
14
15
15
#include < exception>
16
+ #include < stdexcept>
16
17
#include < string>
17
18
#include < type_traits>
18
19
#include < utility>
@@ -387,13 +388,16 @@ class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
387
388
}
388
389
}
389
390
390
- error_already_set (const error_already_set &) = default ;
391
- error_already_set (error_already_set &&) = default ;
391
+ error_already_set (const error_already_set &) noexcept = default ;
392
+ error_already_set (error_already_set &&) noexcept = default ;
392
393
393
394
inline ~error_already_set () override ;
394
395
395
396
const char *what () const noexcept override {
396
- if (m_lazy_what.empty ()) {
397
+ auto *sup_what = std::runtime_error::what ();
398
+ if (sup_what[0 ] != ' \0 ' ) {
399
+ return sup_what;
400
+ } else if (m_lazy_what.empty ()) {
397
401
try {
398
402
m_lazy_what = detail::error_string (m_type.ptr (), m_value.ptr (), m_trace.ptr ());
399
403
} catch (const std::exception &e) {
@@ -407,6 +411,7 @@ class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
407
411
return m_lazy_what.c_str ();
408
412
}
409
413
}
414
+
410
415
assert (!m_lazy_what.empty ());
411
416
return m_lazy_what.c_str ();
412
417
}
@@ -415,7 +420,8 @@ class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
415
420
// / already set it is cleared first. After this call, the current object no longer stores the
416
421
// / error variables (but the `.what()` string is still available).
417
422
void restore () {
418
- what (); // Force-build `.what()`.
423
+ // Abuse assignment operator to cache what()
424
+ std::runtime_error::operator =(std::runtime_error (what ())); // Force-build `.what()`.
419
425
if (m_lazy_what.empty ()) {
420
426
pybind11_fail (" Critical error building lazy error_string()." );
421
427
}
0 commit comments