72 lines
2.5 KiB
C++
72 lines
2.5 KiB
C++
/*
|
|
pybind11/detail/exception_translation.h: means to translate C++ exceptions to Python exceptions
|
|
|
|
Copyright (c) 2024 The Pybind Development Team.
|
|
|
|
All rights reserved. Use of this source code is governed by a
|
|
BSD-style license that can be found in the LICENSE file.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "common.h"
|
|
#include "internals.h"
|
|
|
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
|
|
// Apply all the extensions translators from a list
|
|
// Return true if one of the translators completed without raising an exception
|
|
// itself. Return of false indicates that if there are other translators
|
|
// available, they should be tried.
|
|
inline bool apply_exception_translators(std::forward_list<ExceptionTranslator> &translators) {
|
|
auto last_exception = std::current_exception();
|
|
|
|
for (auto &translator : translators) {
|
|
try {
|
|
translator(last_exception);
|
|
return true;
|
|
} catch (...) {
|
|
last_exception = std::current_exception();
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline void try_translate_exceptions() {
|
|
/* When an exception is caught, give each registered exception
|
|
translator a chance to translate it to a Python exception. First
|
|
all module-local translators will be tried in reverse order of
|
|
registration. If none of the module-locale translators handle
|
|
the exception (or there are no module-locale translators) then
|
|
the global translators will be tried, also in reverse order of
|
|
registration.
|
|
|
|
A translator may choose to do one of the following:
|
|
|
|
- catch the exception and call py::set_error()
|
|
to set a standard (or custom) Python exception, or
|
|
- do nothing and let the exception fall through to the next translator, or
|
|
- delegate translation to the next translator by throwing a new type of exception.
|
|
*/
|
|
|
|
bool handled = with_exception_translators(
|
|
[&](std::forward_list<ExceptionTranslator> &exception_translators,
|
|
std::forward_list<ExceptionTranslator> &local_exception_translators) {
|
|
if (detail::apply_exception_translators(local_exception_translators)) {
|
|
return true;
|
|
}
|
|
if (detail::apply_exception_translators(exception_translators)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
|
|
if (!handled) {
|
|
set_error(PyExc_SystemError, "Exception escaped from default exception translator!");
|
|
}
|
|
}
|
|
|
|
PYBIND11_NAMESPACE_END(detail)
|
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|