Reverted error_already_set to subclass std::runtime_error

This commit is contained in:
Sergei Lebedev 2019-08-28 18:29:35 +01:00
parent f1435c7e6b
commit 60df1435dd
2 changed files with 12 additions and 8 deletions

View File

@ -320,11 +320,11 @@ NAMESPACE_END(detail)
/// thrown to propagate python-side errors back through C++ which can either be caught manually or /// thrown to propagate python-side errors back through C++ which can either be caught manually or
/// else falls back to the function dispatcher (which then raises the captured error back to /// else falls back to the function dispatcher (which then raises the captured error back to
/// python). /// python).
class error_already_set : public std::exception { class error_already_set : public std::runtime_error {
public: public:
/// Constructs a new exception from the current Python error indicator, if any. The current /// Constructs a new exception from the current Python error indicator, if any. The current
/// Python error indicator will be cleared. /// Python error indicator will be cleared.
error_already_set() : std::exception() { error_already_set() : std::runtime_error("") {
PyErr_Fetch(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr()); PyErr_Fetch(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());
} }
@ -334,12 +334,16 @@ public:
inline ~error_already_set(); inline ~error_already_set();
virtual const char* what() const noexcept { virtual const char* what() const noexcept {
if (m_lazy_what.empty()) { try {
if (m_type || m_value || m_trace) if (m_lazy_what.empty()) {
PyErr_NormalizeException(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr()); if (m_type || m_value || m_trace)
m_lazy_what = detail::error_string(m_type.ptr(), m_value.ptr(), m_trace.ptr()); PyErr_NormalizeException(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());
m_lazy_what = detail::error_string(m_type.ptr(), m_value.ptr(), m_trace.ptr());
}
return m_lazy_what.c_str();
} catch (...) {
return "Unknown internal error occurred";
} }
return m_lazy_what.c_str();
} }
/// Give the currently-held error back to Python, if any. If there is currently a Python error /// Give the currently-held error back to Python, if any. If there is currently a Python error

View File

@ -157,7 +157,7 @@ TEST_SUBMODULE(exceptions, m) {
PyErr_SetString(PyExc_ValueError, "foo"); PyErr_SetString(PyExc_ValueError, "foo");
try { try {
throw py::error_already_set(); throw py::error_already_set();
} catch (const py::error_already_set& e) { } catch (const std::runtime_error& e) {
if ((err && e.what() != std::string("ValueError: foo")) || if ((err && e.what() != std::string("ValueError: foo")) ||
(!err && e.what() != std::string("Unknown internal error occurred"))) (!err && e.what() != std::string("Unknown internal error occurred")))
{ {