mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-28 16:11:59 +00:00
Expose exception cause as std::nested_exception
This commit is contained in:
parent
dd3bf7fd12
commit
1bd0eaae06
@ -546,6 +546,8 @@ struct error_fetch_and_normalize {
|
|||||||
return (PyErr_GivenExceptionMatches(m_type.ptr(), exc.ptr()) != 0);
|
return (PyErr_GivenExceptionMatches(m_type.ptr(), exc.ptr()) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::nested_exception get_cause_as_nested() const;
|
||||||
|
|
||||||
// Not protecting these for simplicity.
|
// Not protecting these for simplicity.
|
||||||
object m_type, m_value, m_trace;
|
object m_type, m_value, m_trace;
|
||||||
|
|
||||||
@ -572,13 +574,15 @@ PYBIND11_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 PYBIND11_EXPORT_EXCEPTION error_already_set : public std::exception {
|
class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::exception, public std::nested_exception {
|
||||||
public:
|
public:
|
||||||
/// Fetches the current Python exception (using PyErr_Fetch()), which will clear the
|
/// Fetches the current Python exception (using PyErr_Fetch()), which will clear the
|
||||||
/// current Python error indicator.
|
/// current Python error indicator.
|
||||||
error_already_set()
|
error_already_set()
|
||||||
: m_fetched_error{new detail::error_fetch_and_normalize("pybind11::error_already_set"),
|
: m_fetched_error{new detail::error_fetch_and_normalize("pybind11::error_already_set"),
|
||||||
m_fetched_error_deleter} {}
|
m_fetched_error_deleter} {
|
||||||
|
static_cast<std::nested_exception&>(*this) = m_fetched_error->get_cause_as_nested();
|
||||||
|
}
|
||||||
|
|
||||||
/// The what() result is built lazily on demand.
|
/// The what() result is built lazily on demand.
|
||||||
/// WARNING: This member function needs to acquire the Python GIL. This can lead to
|
/// WARNING: This member function needs to acquire the Python GIL. This can lead to
|
||||||
@ -2327,6 +2331,20 @@ bool object_api<D>::rich_compare(object_api const &other, int value) const {
|
|||||||
return rv == 1;
|
return rv == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::nested_exception error_fetch_and_normalize::get_cause_as_nested() const {
|
||||||
|
auto cause = reinterpret_steal<object>(PyException_GetCause(m_value.ptr()));
|
||||||
|
if (not cause or cause.is_none())
|
||||||
|
return std::nested_exception();
|
||||||
|
auto typ = type::of(cause);
|
||||||
|
auto tb = reinterpret_steal<object>(PyException_GetTraceback(cause.ptr()));
|
||||||
|
PyErr_Restore(typ.release().ptr(), cause.release().ptr(), tb.release().ptr());
|
||||||
|
try {
|
||||||
|
throw error_already_set();
|
||||||
|
} catch (...) {
|
||||||
|
return std::nested_exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define PYBIND11_MATH_OPERATOR_UNARY(op, fn) \
|
#define PYBIND11_MATH_OPERATOR_UNARY(op, fn) \
|
||||||
template <typename D> \
|
template <typename D> \
|
||||||
object object_api<D>::op() const { \
|
object object_api<D>::op() const { \
|
||||||
|
Loading…
Reference in New Issue
Block a user