LSST Applications  21.0.0-1-g8760c09+3ec9fa6d59,21.0.0-1-ga51b5d4+1ae1d287e8,21.0.0-14-g8332f57+53eed6efa3,21.0.0-16-g26cb9d6+200c335b02,21.0.0-16-g4bab731+7b753826ce,21.0.0-16-gf8f8bd3+485e975e6b,21.0.0-17-g535a0ce+caa2b9ee35,21.0.0-19-g1f131b1+29afaafaac,21.0.0-2-g103fe59+1a3971b589,21.0.0-2-g45278ab+3ec9fa6d59,21.0.0-2-g5242d73+0be025d221,21.0.0-2-g7f82c8f+6d5aba68d9,21.0.0-2-ga326454+6d5aba68d9,21.0.0-2-gde069b7+135055f2fa,21.0.0-2-gecfae73+f2022f71e2,21.0.0-2-gfc62afb+0be025d221,21.0.0-21-gec9c878+73f7dbf5d1,21.0.0-22-g8939e615+6101bd4b5e,21.0.0-3-g357aad2+66d02658a4,21.0.0-3-g4a4ce7f+0be025d221,21.0.0-3-g4be5c26+0be025d221,21.0.0-3-gd7ab7aa+a13d88a6a5,21.0.0-3-ge02ed75+caa2b9ee35,21.0.0-30-gf21da11f8+958f744973,21.0.0-4-g591bb35+caa2b9ee35,21.0.0-4-g65b4814+29afaafaac,21.0.0-4-g7dab645+dd55007106,21.0.0-4-ge8a399c+3c33e53e4b,21.0.0-5-g8c1d971+75b22be884,21.0.0-5-gcb07a25+7075ac2890,21.0.0-5-gcc89fd6+a13d88a6a5,21.0.0-5-gd00fb1e+3ed68df9f8,21.0.0-6-gc675373+0be025d221,21.0.0-7-gdf92d54+3ec9fa6d59,21.0.0-77-gb560965c+1db212ba20,21.0.0-8-g5674e7b+aee49eae85,21.0.0-9-gc2127a9+f3c7279034,master-gac4afde19b+caa2b9ee35,w.2021.18
LSST Data Management Base Package
exceptions.cc
Go to the documentation of this file.
1 /*
2  * This file is part of pex_exceptions.
3  *
4  * Developed for the LSST Data Management System.
5  * This product includes software developed by the LSST Project
6  * (https://www.lsst.org).
7  * See the COPYRIGHT file at the top-level directory of this distribution
8  * for details of code ownership.
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
24 #include "pybind11/pybind11.h"
25 
26 #include <sstream>
27 
30 
31 using namespace lsst::pex::exceptions;
32 
33 namespace py = pybind11;
34 
35 namespace lsst {
36 namespace pex {
37 namespace exceptions {
38 namespace {
39 // Helper function to show a Python warning when exception translation fails.
40 void tryLsstExceptionWarn(const char *message) {
41  // Try to warn that exception translation failed, if we fail, clear the exception raised by the
42  // warning attempt so we can raise a less-informative exception based on the original.
43  int s = PyErr_WarnEx(PyExc_Warning, message, 1);
44  if (s) {
45  PyErr_Clear();
46  }
47 }
48 
63 void raiseLsstException(py::object &pyex) {
64  static auto module =
65  py::reinterpret_borrow<py::object>(PyImport_ImportModule("lsst.pex.exceptions.wrappers"));
66  if (!module.ptr()) {
67  tryLsstExceptionWarn("Failed to import C++ Exception wrapper module.");
68  } else {
69  static auto translate =
70  py::reinterpret_borrow<py::object>(PyObject_GetAttrString(module.ptr(), "translate"));
71  if (!translate.ptr()) {
72  tryLsstExceptionWarn("Failed to find translation function for C++ Exceptions.");
73  } else {
74  // Calling the Python translate() returns an instance of the appropriate Python
75  // exception that wraps the C++ exception instance that we give it.
76  auto instance = py::reinterpret_steal<py::object>(
77  PyObject_CallFunctionObjArgs(translate.ptr(), pyex.ptr(), NULL));
78  if (!instance.ptr()) {
79  // We actually expect a null return here, as translate() should raise an exception
80  tryLsstExceptionWarn("Failed to translate C++ Exception to Python.");
81  } else {
82  auto type = py::reinterpret_borrow<py::object>(PyObject_Type(instance.ptr()));
83  PyErr_SetObject(type.ptr(), instance.ptr());
84  }
85  }
86  }
87 }
88 } // namespace
89 
90 PYBIND11_MODULE(exceptions, mod) {
91  py::class_<Tracepoint> clsTracepoint(mod, "Tracepoint");
92 
93  clsTracepoint.def(py::init<char const *, int, char const *, std::string const &>())
94  .def_readwrite("_file", &Tracepoint::_file)
95  .def_readwrite("_line", &Tracepoint::_line)
96  .def_readwrite("_func", &Tracepoint::_func)
97  .def_readwrite("_message", &Tracepoint::_message);
98 
99  py::class_<Exception> clsException(mod, "Exception");
100 
101  clsException.def(py::init<std::string const &>())
102  .def("addMessage", &Exception::addMessage)
103  .def("getTraceback", &Exception::getTraceback)
104  .def("addToStream", &Exception::addToStream)
105  .def("what", &Exception::what)
106  .def("getType", &Exception::getType)
107  .def("clone", &Exception::clone)
108  .def("asString",
109  [](Exception &self) -> std::string {
110  std::ostringstream stream;
111  self.addToStream(stream);
112  return stream.str();
113  })
114  .def("__repr__", [](Exception &self) -> std::string {
116  s << "Exception('" << self.what() << "')";
117  return s.str();
118  });
119 
120  py::class_<LogicError, Exception> clsLogicError(mod, "LogicError");
121  clsLogicError.def(py::init<std::string const &>());
122 
123  py::class_<NotFoundError, Exception> clsNotFoundError(mod, "NotFoundError");
124  clsNotFoundError.def(py::init<std::string const &>());
125 
126  py::class_<RuntimeError, Exception> clsRuntimeError(mod, "RuntimeError");
127  clsRuntimeError.def(py::init<std::string const &>());
128 
129  py::class_<IoError, RuntimeError> clsIoError(mod, "IoError");
130  clsIoError.def(py::init<std::string const &>());
131 
132  py::class_<OverflowError, RuntimeError> clsOverflowError(mod, "OverflowError");
133  clsOverflowError.def(py::init<std::string const &>());
134 
135  py::class_<RangeError, RuntimeError> clsRangeError(mod, "RangeError");
136  clsRangeError.def(py::init<std::string const &>());
137 
138  py::class_<TypeError, LogicError> clsTypeError(mod, "TypeError");
139  clsTypeError.def(py::init<std::string const &>());
140 
141  py::class_<UnderflowError, RuntimeError> clsUnderflowError(mod, "UnderflowError");
142  clsUnderflowError.def(py::init<std::string const &>());
143 
144  py::class_<DomainError, LogicError> clsDomainError(mod, "DomainError");
145  clsDomainError.def(py::init<std::string const &>());
146 
147  py::class_<InvalidParameterError, LogicError> clsInvalidParameterError(mod, "InvalidParameterError");
148  clsInvalidParameterError.def(py::init<std::string const &>());
149 
150  py::class_<LengthError, LogicError> clsLengthError(mod, "LengthError");
151  clsLengthError.def(py::init<std::string const &>());
152 
153  py::class_<OutOfRangeError, LogicError> clsOutOfRangeError(mod, "OutOfRangeError");
154  clsOutOfRangeError.def(py::init<std::string const &>());
155 
156  py::register_exception_translator([](std::exception_ptr p) {
157  try {
158  if (p) std::rethrow_exception(p);
159  } catch (const Exception &e) {
160  py::object current_exception;
161  current_exception = py::cast(e.clone(), py::return_value_policy::take_ownership);
162  raiseLsstException(current_exception);
163  }
164  });
165 }
166 
167 } // namespace exceptions
168 } // namespace pex
169 } // namespace lsst
table::Key< int > type
Definition: Detector.cc:163
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
Traceback const & getTraceback(void) const noexcept
Retrieve the list of tracepoints associated with an exception.
Definition: Exception.cc:79
virtual char const * getType(void) const noexcept
Return the fully-specified C++ type of a pointer to the exception.
Definition: Exception.cc:101
virtual char const * what(void) const noexcept
Return a character string summarizing this exception.
Definition: Exception.cc:99
virtual Exception * clone(void) const
Return a copy of the exception as an Exception pointer.
Definition: Exception.cc:103
void addMessage(char const *file, int line, char const *func, std::string const &message)
Add a tracepoint and a message to an exception before rethrowing it (access via LSST_EXCEPT_ADD).
Definition: Exception.cc:49
virtual std::ostream & addToStream(std::ostream &stream) const
Add a text representation of this exception, including its traceback with messages,...
Definition: Exception.cc:81
PYBIND11_MODULE(exceptions, mod)
Definition: exceptions.cc:90
A base class for image defects.
T rethrow_exception(T... args)
T str(T... args)