summaryrefslogtreecommitdiff
path: root/libs/python/src/errors.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-06-25 22:59:01 +0000
committer <>2013-09-27 11:49:28 +0000
commit8c4528713d907ee2cfd3bfcbbad272c749867f84 (patch)
treec09e2ce80f47b90c85cc720f5139089ad9c8cfff /libs/python/src/errors.cpp
downloadboost-tarball-baserock/morph.tar.gz
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_54_0.tar.bz2.boost_1_54_0baserock/morph
Diffstat (limited to 'libs/python/src/errors.cpp')
-rw-r--r--libs/python/src/errors.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/libs/python/src/errors.cpp b/libs/python/src/errors.cpp
new file mode 100644
index 000000000..34ea22f43
--- /dev/null
+++ b/libs/python/src/errors.cpp
@@ -0,0 +1,105 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PYTHON_SOURCE
+# define BOOST_PYTHON_SOURCE
+#endif
+
+#include <boost/python/errors.hpp>
+#include <boost/cast.hpp>
+#include <boost/python/detail/exception_handler.hpp>
+
+namespace boost { namespace python {
+
+error_already_set::~error_already_set() {}
+
+// IMPORTANT: this function may only be called from within a catch block!
+BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f)
+{
+ try
+ {
+ if (detail::exception_handler::chain)
+ return detail::exception_handler::chain->handle(f);
+ f();
+ return false;
+ }
+ catch(const boost::python::error_already_set&)
+ {
+ // The python error reporting has already been handled.
+ }
+ catch(const std::bad_alloc&)
+ {
+ PyErr_NoMemory();
+ }
+ catch(const bad_numeric_cast& x)
+ {
+ PyErr_SetString(PyExc_OverflowError, x.what());
+ }
+ catch(const std::out_of_range& x)
+ {
+ PyErr_SetString(PyExc_IndexError, x.what());
+ }
+ catch(const std::invalid_argument& x)
+ {
+ PyErr_SetString(PyExc_ValueError, x.what());
+ }
+ catch(const std::exception& x)
+ {
+ PyErr_SetString(PyExc_RuntimeError, x.what());
+ }
+ catch(...)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception");
+ }
+ return true;
+}
+
+void BOOST_PYTHON_DECL throw_error_already_set()
+{
+ throw error_already_set();
+}
+
+namespace detail {
+
+bool exception_handler::operator()(function0<void> const& f) const
+{
+ if (m_next)
+ {
+ return m_next->handle(f);
+ }
+ else
+ {
+ f();
+ return false;
+ }
+}
+
+exception_handler::exception_handler(handler_function const& impl)
+ : m_impl(impl)
+ , m_next(0)
+{
+ if (chain != 0)
+ tail->m_next = this;
+ else
+ chain = this;
+ tail = this;
+}
+
+exception_handler* exception_handler::chain;
+exception_handler* exception_handler::tail;
+
+BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f)
+{
+ // the constructor links the new object into a handler chain, so
+ // this object isn't actaully leaked (until, of course, the
+ // interpreter exits).
+ new exception_handler(f);
+}
+
+} // namespace boost::python::detail
+
+}} // namespace boost::python
+
+