Alexandria 2.27.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
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
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 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
70auto Exception::getTraceback() const -> const std::list<Location>& {
71 return m_traceback;
72}
73
74const Exception& Exception::log(log4cpp::Priority::Value level, Elements::Logging& logger) const {
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)
STL namespace.
T str(T... args)
Traceback location.
Definition: Exceptions.h:35