Alexandria  2.27.0
SDC-CH common library for the Euclid project
Exceptions.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2022 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
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 
26 namespace py = boost::python;
27 
28 namespace 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  py::handle<> handle_type(ptype);
38  py::handle<> handle_value(pvalue);
39  py::handle<> handle_traceback(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  py::object traceback(handle_traceback);
54  while (traceback) {
55  Location loc;
56  loc.lineno = py::extract<long>(traceback.attr("tb_lineno"));
57  loc.filename = py::extract<std::string>(traceback.attr("tb_frame").attr("f_code").attr("co_filename"));
58  loc.funcname = py::extract<std::string>(traceback.attr("tb_frame").attr("f_code").attr("co_name"));
59 
60  m_traceback.emplace_back(loc);
61 
62  traceback = traceback.attr("tb_next");
63  }
64  }
65 
66  // Done
67  PyErr_Clear();
68 }
69 
70 auto Exception::getTraceback() const -> const std::list<Location>& {
71  return m_traceback;
72 }
73 
75  for (auto& trace : m_traceback) {
77  msg << "File \"" << trace.filename << "\", line " << trace.lineno << ", in " << trace.funcname;
78  logger.log(level, msg.str());
79  }
80  return *this;
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)
std::list< Location > m_traceback
Definition: Exceptions.h:59
const std::list< Location > & getTraceback() const
Definition: Exceptions.cpp:70
const Exception & log(log4cpp::Priority::Value level, Elements::Logging &logger) const
Log error message and traceback.
Definition: Exceptions.cpp:74
T empty(T... args)
boost::variant< bool, int64_t, double, AttributeSet > Value
Definition: Node.h:88
STL namespace.
T str(T... args)
Traceback location.
Definition: Exceptions.h:35