Alexandria 2.31.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
Exceptions.cpp
Go to the documentation of this file.
1
19#include "Pyston/Exceptions.h"
20#include "Pyston/GIL.h"
21#include <Python.h>
22#include <boost/python/extract.hpp>
23#include <boost/python/handle.hpp>
24#include <boost/python/object.hpp>
25
26namespace py = boost::python;
27
28namespace Pyston {
29
31 GILLocker locker;
32
33 PyObject *ptype, *pvalue, *ptraceback;
34 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
35 PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
36
37 m_error_type = py::object(py::handle<>(ptype));
38 m_error_value = py::object(py::handle<>(pvalue));
39 m_error_traceback = py::object(py::handle<>(py::allow_null(ptraceback)));
40
41 // Get the error message and exception type
42 py::object err_msg_obj(py::handle<>(PyObject_Str(pvalue)));
43 m_error_msg = py::extract<std::string>(err_msg_obj);
44 if (m_error_msg.empty()) {
45 py::object err_repr_obj(py::handle<>(PyObject_Repr(pvalue)));
46 m_error_msg = py::extract<std::string>(err_repr_obj);
47 }
48 py::object err_msg_type(py::handle<>(PyObject_GetAttrString(ptype, "__name__")));
49 m_error_msg = std::string(py::extract<std::string>(err_msg_type)) + ": " + m_error_msg;
50
51 // Generate traceback
52 if (ptraceback) {
53 for (auto traceback = m_error_traceback; traceback; traceback = traceback.attr("tb_next")) {
54 Location loc;
55 loc.lineno = py::extract<long>(traceback.attr("tb_lineno"));
56 loc.filename = py::extract<std::string>(traceback.attr("tb_frame").attr("f_code").attr("co_filename"));
57 loc.funcname = py::extract<std::string>(traceback.attr("tb_frame").attr("f_code").attr("co_name"));
58 m_traceback.emplace_back(loc);
59 }
60 }
61
62 // Done
63 PyErr_Clear();
64}
65
66auto Exception::getTraceback() const -> const std::list<Location>& {
67 return m_traceback;
68}
69
70const Exception& Exception::log(log4cpp::Priority::Value level, Elements::Logging& logger) const {
71 for (auto& trace : m_traceback) {
73 msg << "File \"" << trace.filename << "\", line " << trace.lineno << ", in " << trace.funcname;
74 logger.log(level, msg.str());
75 }
76 return *this;
77}
78
79void Exception::restore() const {
80 PyErr_Restore(py::xincref(m_error_type.ptr()), py::xincref(m_error_value.ptr()), py::xincref(m_error_traceback.ptr()));
81}
82
83} // end of namespace Pyston
static Elements::Logging logger
Logger.
Definition Example.cpp:55
std::string m_error_msg
void log(log4cpp::Priority::Value level, const std::string &logMessage)
boost::python::object m_error_traceback
Definition Exceptions.h:66
void restore() const
Call PyErr_Restore and restore the error. This can be used when Pyston::Exception goes back to Python...
std::list< Location > m_traceback
Definition Exceptions.h:63
const std::list< Location > & getTraceback() const
boost::python::object m_error_type
Definition Exceptions.h:64
boost::python::object m_error_value
Definition Exceptions.h:65
const Exception & log(log4cpp::Priority::Value level, Elements::Logging &logger) const
Log error message and traceback.
T empty(T... args)
STL namespace.
T str(T... args)
Traceback location.
Definition Exceptions.h:36