This is an automated email from the ASF dual-hosted git repository.

szaszm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git


The following commit(s) were added to refs/heads/main by this push:
     new 3fac4a9a9 MINIFICPP-2766 Preventing C++ exceptions from unwinding the 
stack ove…
3fac4a9a9 is described below

commit 3fac4a9a91aa5a0dc6695a07631c3116aa309cd4
Author: cccs-jsjm <[email protected]>
AuthorDate: Thu Apr 9 19:25:52 2026 +0200

    MINIFICPP-2766 Preventing C++ exceptions from unwinding the stack ove…
    
    …r the Python interpreter.
    
    Closes #2154
    
    Signed-off-by: Marton Szasz <[email protected]>
---
 extensions/python/PythonBindings.h              | 11 +++++++++++
 extensions/python/types/PyDataConverter.cpp     |  4 ++++
 extensions/python/types/PyInputStream.cpp       |  2 ++
 extensions/python/types/PyLogger.cpp            | 10 ++++++++++
 extensions/python/types/PyOutputStream.cpp      |  2 ++
 extensions/python/types/PyProcessContext.cpp    | 20 ++++++++++++++++++++
 extensions/python/types/PyProcessSession.cpp    | 20 ++++++++++++++++++++
 extensions/python/types/PyProcessor.cpp         |  8 ++++++++
 extensions/python/types/PyRecordSetReader.cpp   |  2 ++
 extensions/python/types/PyRecordSetWriter.cpp   |  2 ++
 extensions/python/types/PyRelationship.cpp      |  4 ++++
 extensions/python/types/PySSLContextService.cpp |  8 ++++++++
 extensions/python/types/PyScriptFlowFile.cpp    | 14 ++++++++++++++
 extensions/python/types/PyStateManager.cpp      |  8 ++++++++
 14 files changed, 115 insertions(+)

diff --git a/extensions/python/PythonBindings.h 
b/extensions/python/PythonBindings.h
index dbccad922..eeae3fd74 100644
--- a/extensions/python/PythonBindings.h
+++ b/extensions/python/PythonBindings.h
@@ -23,6 +23,17 @@
 
 #include "types/Types.h"
 
+#define PYTHON_METHOD_BEGIN \
+  try {
+#define PYTHON_METHOD_END \
+  } catch (const std::exception& e) { \
+    PyErr_Format(PyExc_RuntimeError, "C++ binding error: %s", e.what()); \
+    return nullptr; \
+  } catch (...) { \
+    PyErr_SetString(PyExc_Exception, "Unknown C++ exception"); \
+    return nullptr; \
+  }
+
 namespace org::apache::nifi::minifi::extensions::python {
 
 PyMODINIT_FUNC
diff --git a/extensions/python/types/PyDataConverter.cpp 
b/extensions/python/types/PyDataConverter.cpp
index a97902c5d..90d6ef3b6 100644
--- a/extensions/python/types/PyDataConverter.cpp
+++ b/extensions/python/types/PyDataConverter.cpp
@@ -23,6 +23,7 @@
 namespace org::apache::nifi::minifi::extensions::python {
 
 PyObject* timePeriodStringToMilliseconds(PyObject* /*self*/, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   const char* time_period_str = nullptr;
   if (!PyArg_ParseTuple(args, "s", &time_period_str)) {
     return nullptr;
@@ -31,9 +32,11 @@ PyObject* timePeriodStringToMilliseconds(PyObject* /*self*/, 
PyObject* args) {
   auto milliseconds = 
core::TimePeriodValue(std::string(time_period_str)).getMilliseconds().count();
 
   return object::returnReference(milliseconds);
+  PYTHON_METHOD_END
 }
 
 PyObject* dataSizeStringToBytes(PyObject* /*self*/, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   const char* data_size_str = nullptr;
   if (!PyArg_ParseTuple(args, "s", &data_size_str)) {
     return nullptr;
@@ -42,6 +45,7 @@ PyObject* dataSizeStringToBytes(PyObject* /*self*/, PyObject* 
args) {
   uint64_t bytes = core::DataSizeValue(std::string(data_size_str)).getValue();
 
   return object::returnReference(bytes);
+  PYTHON_METHOD_END
 }
 
 }  // namespace org::apache::nifi::minifi::extensions::python
diff --git a/extensions/python/types/PyInputStream.cpp 
b/extensions/python/types/PyInputStream.cpp
index c7f4b9fc3..6a5b6649b 100644
--- a/extensions/python/types/PyInputStream.cpp
+++ b/extensions/python/types/PyInputStream.cpp
@@ -60,6 +60,7 @@ int PyInputStream::init(PyInputStream* self, PyObject* args, 
PyObject*) {
 }
 
 PyObject* PyInputStream::read(PyInputStream* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto input_stream = self->input_stream_.lock();
   if (!input_stream) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -79,6 +80,7 @@ PyObject* PyInputStream::read(PyInputStream* self, PyObject* 
args) {
 
   const auto read = input_stream->read(buffer);
   return 
object::returnReference(OwnedBytes::fromStringAndSize(std::string_view(reinterpret_cast<const
 char*>(buffer.data()), read)));
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyInputStream::typeObject() {
diff --git a/extensions/python/types/PyLogger.cpp 
b/extensions/python/types/PyLogger.cpp
index 78b9c3f26..2525eeb97 100644
--- a/extensions/python/types/PyLogger.cpp
+++ b/extensions/python/types/PyLogger.cpp
@@ -60,6 +60,7 @@ int PyLogger::init(PyLogger* self, PyObject* args, PyObject*) 
{
 }
 
 PyObject* PyLogger::error(PyLogger* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto logger = self->logger_.lock();
   if (logger == nullptr) {
     PyErr_SetString(PyExc_AttributeError, "internal 'logger' instance is 
null");
@@ -72,9 +73,11 @@ PyObject* PyLogger::error(PyLogger* self, PyObject* args) {
   }
   logger->log_error("{}", message);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyLogger::warn(PyLogger* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto logger = self->logger_.lock();
   if (logger == nullptr) {
     PyErr_SetString(PyExc_AttributeError, "internal 'logger' instance is 
null");
@@ -87,9 +90,11 @@ PyObject* PyLogger::warn(PyLogger* self, PyObject* args) {
   }
   logger->log_warn("{}", message);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyLogger::info(PyLogger* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto logger = self->logger_.lock();
   if (logger == nullptr) {
     PyErr_SetString(PyExc_AttributeError, "internal 'logger' instance is 
null");
@@ -102,9 +107,11 @@ PyObject* PyLogger::info(PyLogger* self, PyObject* args) {
   }
   logger->log_info("{}", message);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyLogger::debug(PyLogger* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto logger = self->logger_.lock();
   if (logger == nullptr) {
     PyErr_SetString(PyExc_AttributeError, "internal 'logger' instance is 
null");
@@ -117,9 +124,11 @@ PyObject* PyLogger::debug(PyLogger* self, PyObject* args) {
   }
   logger->log_debug("{}", message);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyLogger::trace(PyLogger* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto logger = self->logger_.lock();
   if (logger == nullptr) {
     PyErr_SetString(PyExc_AttributeError, "internal 'logger' instance is 
null");
@@ -132,6 +141,7 @@ PyObject* PyLogger::trace(PyLogger* self, PyObject* args) {
   }
   logger->log_trace("{}", message);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyLogger::typeObject() {
diff --git a/extensions/python/types/PyOutputStream.cpp 
b/extensions/python/types/PyOutputStream.cpp
index d96b7ac1a..521d918c7 100644
--- a/extensions/python/types/PyOutputStream.cpp
+++ b/extensions/python/types/PyOutputStream.cpp
@@ -56,6 +56,7 @@ int PyOutputStream::init(PyOutputStream* self, PyObject* 
args, PyObject*) {
 }
 
 PyObject* PyOutputStream::write(PyOutputStream* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto output_stream = self->output_stream_.lock();
   if (!output_stream) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -73,6 +74,7 @@ PyObject* PyOutputStream::write(PyOutputStream* self, 
PyObject* args) {
     return nullptr;
   }
   return object::returnReference(output_stream->write(gsl::make_span(buffer, 
length).as_span<const std::byte>()));
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyOutputStream::typeObject() {
diff --git a/extensions/python/types/PyProcessContext.cpp 
b/extensions/python/types/PyProcessContext.cpp
index f207faff6..bbebe2e4c 100644
--- a/extensions/python/types/PyProcessContext.cpp
+++ b/extensions/python/types/PyProcessContext.cpp
@@ -72,6 +72,7 @@ int PyProcessContext::init(PyProcessContext* self, PyObject* 
args, PyObject*) {
 }
 
 PyObject* PyProcessContext::getProperty(PyProcessContext* self, PyObject* 
args) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -102,9 +103,11 @@ PyObject* PyProcessContext::getProperty(PyProcessContext* 
self, PyObject* args)
     return object::returnReference(*property_value);
   }
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::getRawProperty(PyProcessContext* self, PyObject* 
args) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -121,9 +124,11 @@ PyObject* 
PyProcessContext::getRawProperty(PyProcessContext* self, PyObject* arg
     return object::returnReference(*property_value);
   }
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::getDynamicProperty(PyProcessContext* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -153,9 +158,11 @@ PyObject* 
PyProcessContext::getDynamicProperty(PyProcessContext* self, PyObject*
     return object::returnReference(*property_value);
   }
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::getRawDynamicProperty(PyProcessContext* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -172,9 +179,11 @@ PyObject* 
PyProcessContext::getRawDynamicProperty(PyProcessContext* self, PyObje
     return object::returnReference(*property_value);
   }
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::getDynamicPropertyKeys(PyProcessContext* self, 
PyObject*) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -188,9 +197,11 @@ PyObject* 
PyProcessContext::getDynamicPropertyKeys(PyProcessContext* self, PyObj
   }
 
   return object::returnReference(py_properties);
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::getStateManager(PyProcessContext* self, PyObject*) 
{
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -198,9 +209,11 @@ PyObject* 
PyProcessContext::getStateManager(PyProcessContext* self, PyObject*) {
   }
 
   return object::returnReference(context->getStateManager());
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::getControllerService(PyProcessContext* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -228,9 +241,11 @@ PyObject* 
PyProcessContext::getControllerService(PyProcessContext* self, PyObjec
   }
 
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::getName(PyProcessContext* self, PyObject*) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -238,9 +253,11 @@ PyObject* PyProcessContext::getName(PyProcessContext* 
self, PyObject*) {
   }
 
   return object::returnReference(context->getProcessorInfo().getName());
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::getProperties(PyProcessContext* self, PyObject*) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -256,9 +273,11 @@ PyObject* 
PyProcessContext::getProperties(PyProcessContext* self, PyObject*) {
   }
 
   return object::returnReference(py_properties);
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessContext::yieldResources(PyProcessContext* self, PyObject*) {
+  PYTHON_METHOD_BEGIN
   auto context = self->process_context_;
   if (!context) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process context 
outside 'on_trigger'");
@@ -268,6 +287,7 @@ PyObject* 
PyProcessContext::yieldResources(PyProcessContext* self, PyObject*) {
   context->yield();
 
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyProcessContext::typeObject() {
diff --git a/extensions/python/types/PyProcessSession.cpp 
b/extensions/python/types/PyProcessSession.cpp
index ff20af314..b0170cafb 100644
--- a/extensions/python/types/PyProcessSession.cpp
+++ b/extensions/python/types/PyProcessSession.cpp
@@ -168,6 +168,7 @@ int PyProcessSessionObject::init(PyProcessSessionObject* 
self, PyObject* args, P
 }
 
 PyObject* PyProcessSessionObject::get(PyProcessSessionObject* self, PyObject*) 
{
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -176,9 +177,11 @@ PyObject* 
PyProcessSessionObject::get(PyProcessSessionObject* self, PyObject*) {
   if (auto flow_file = session->get())
     return object::returnReference(std::weak_ptr(flow_file));
   return object::returnReference(nullptr);
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessSessionObject::create(PyProcessSessionObject* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -198,9 +201,11 @@ PyObject* 
PyProcessSessionObject::create(PyProcessSessionObject* self, PyObject*
   if (auto flow_file = session->create(parent_flow_file))
     return object::returnReference(std::weak_ptr(flow_file));
   return object::returnReference(nullptr);
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessSessionObject::clone(PyProcessSessionObject* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -215,9 +220,11 @@ PyObject* 
PyProcessSessionObject::clone(PyProcessSessionObject* self, PyObject*
   if (auto cloned_flow_file = session->clone(flow_file))
     return object::returnReference(std::weak_ptr(cloned_flow_file));
   return object::returnReference(nullptr);
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessSessionObject::remove(PyProcessSessionObject* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -230,9 +237,11 @@ PyObject* 
PyProcessSessionObject::remove(PyProcessSessionObject* self, PyObject*
   const auto flow_file = 
reinterpret_cast<PyScriptFlowFile*>(script_flow_file)->script_flow_file_.lock();
   session->remove(flow_file);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessSessionObject::read(PyProcessSessionObject* self, PyObject* 
args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -252,9 +261,11 @@ PyObject* 
PyProcessSessionObject::read(PyProcessSessionObject* self, PyObject* a
   }
   session->read(flow_file, BorrowedObject(callback));
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessSessionObject::write(PyProcessSessionObject* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -274,9 +285,11 @@ PyObject* 
PyProcessSessionObject::write(PyProcessSessionObject* self, PyObject*
   }
   session->write(flow_file, BorrowedObject(callback));
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessSessionObject::transfer(PyProcessSessionObject* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -296,9 +309,11 @@ PyObject* 
PyProcessSessionObject::transfer(PyProcessSessionObject* self, PyObjec
   }
   session->transfer(flow_file, 
reinterpret_cast<PyRelationship*>(relationship)->relationship_);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* 
PyProcessSessionObject::transferToCustomRelationship(PyProcessSessionObject* 
self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -331,9 +346,11 @@ PyObject* 
PyProcessSessionObject::transferToCustomRelationship(PyProcessSessionO
   BorrowedStr name = BorrowedStr::fromTuple(args, 0);
   session->transferToCustomRelationship(flow_file, relationship_name_str);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessSessionObject::getContentsAsBytes(PyProcessSessionObject* 
self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -347,9 +364,11 @@ PyObject* 
PyProcessSessionObject::getContentsAsBytes(PyProcessSessionObject* sel
   auto content = session->getContentsAsString(flow_file);
 
   return PyBytes_FromStringAndSize(content.c_str(), 
gsl::narrow<Py_ssize_t>(content.size()));
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessSessionObject::putAttribute(PyProcessSessionObject* self, 
PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto session = self->process_session_.lock();
   if (!session) {
     PyErr_SetString(PyExc_AttributeError, "tried reading process session 
outside 'on_trigger'");
@@ -388,6 +407,7 @@ PyObject* 
PyProcessSessionObject::putAttribute(PyProcessSessionObject* self, PyO
 
   session->putAttribute(flow_file, attribute_key_str, attribute_value_str);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyProcessSessionObject::typeObject() {
diff --git a/extensions/python/types/PyProcessor.cpp 
b/extensions/python/types/PyProcessor.cpp
index d39b9c3ed..73d2d6267 100644
--- a/extensions/python/types/PyProcessor.cpp
+++ b/extensions/python/types/PyProcessor.cpp
@@ -79,6 +79,7 @@ int PyProcessor::init(PyProcessor* self, PyObject* args, 
PyObject*) {
 }
 
 PyObject* PyProcessor::setSupportsDynamicProperties(PyProcessor* self, 
PyObject*) {
+  PYTHON_METHOD_BEGIN
   auto processor = self->processor_.lock();
   if (!processor) {
     PyErr_SetString(PyExc_AttributeError, "tried reading processor outside 
'on_trigger'");
@@ -87,9 +88,11 @@ PyObject* 
PyProcessor::setSupportsDynamicProperties(PyProcessor* self, PyObject*
 
   processor->setSupportsDynamicProperties();
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessor::setDescription(PyProcessor* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto processor = self->processor_.lock();
   if (!processor) {
     PyErr_SetString(PyExc_AttributeError, "tried reading processor outside 
'on_trigger'");
@@ -102,9 +105,11 @@ PyObject* PyProcessor::setDescription(PyProcessor* self, 
PyObject* args) {
   }
   processor->setDescription(std::string(description));
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessor::setVersion(PyProcessor* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto processor = self->processor_.lock();
   if (!processor) {
     PyErr_SetString(PyExc_AttributeError, "tried reading processor outside 
'on_trigger'");
@@ -117,9 +122,11 @@ PyObject* PyProcessor::setVersion(PyProcessor* self, 
PyObject* args) {
   }
   processor->setVersion(std::string(version));
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyProcessor::addProperty(PyProcessor* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   auto processor = self->processor_.lock();
   if (!processor) {
     PyErr_SetString(PyExc_AttributeError, "tried reading processor outside 
'on_trigger'");
@@ -190,6 +197,7 @@ PyObject* PyProcessor::addProperty(PyProcessor* self, 
PyObject* args) {
   processor->addProperty(name.toUtf8String(), description.toUtf8String(), 
default_value, is_required, supports_expression_language, sensitive,
       validator_value, allowable_values, controller_service_type_name);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyProcessor::typeObject() {
diff --git a/extensions/python/types/PyRecordSetReader.cpp 
b/extensions/python/types/PyRecordSetReader.cpp
index f168aa68a..6d58b9bf0 100644
--- a/extensions/python/types/PyRecordSetReader.cpp
+++ b/extensions/python/types/PyRecordSetReader.cpp
@@ -61,6 +61,7 @@ int PyRecordSetReader::init(PyRecordSetReader* self, 
PyObject* args, PyObject*)
 }
 
 PyObject* PyRecordSetReader::read(PyRecordSetReader* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   gsl_Expects(self && args);
   auto record_set_reader = self->record_set_reader_.lock();
   if (!record_set_reader) {
@@ -106,6 +107,7 @@ PyObject* PyRecordSetReader::read(PyRecordSetReader* self, 
PyObject* args) {
     records.append(std::string{buffer.GetString(), buffer.GetSize()});
   }
   return object::returnReference(records);
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyRecordSetReader::typeObject() {
diff --git a/extensions/python/types/PyRecordSetWriter.cpp 
b/extensions/python/types/PyRecordSetWriter.cpp
index caca438c2..6a8239892 100644
--- a/extensions/python/types/PyRecordSetWriter.cpp
+++ b/extensions/python/types/PyRecordSetWriter.cpp
@@ -61,6 +61,7 @@ int PyRecordSetWriter::init(PyRecordSetWriter* self, 
PyObject* args, PyObject*)
 }
 
 PyObject* PyRecordSetWriter::write(PyRecordSetWriter* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   gsl_Expects(self && args);
   auto record_set_writer = self->record_set_writer_.lock();
   if (!record_set_writer) {
@@ -103,6 +104,7 @@ PyObject* PyRecordSetWriter::write(PyRecordSetWriter* self, 
PyObject* args) {
 
   record_set_writer->write(record_set, flow_file, 
process_session->getSession());
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyRecordSetWriter::typeObject() {
diff --git a/extensions/python/types/PyRelationship.cpp 
b/extensions/python/types/PyRelationship.cpp
index 20b87a4a3..fdb23004e 100644
--- a/extensions/python/types/PyRelationship.cpp
+++ b/extensions/python/types/PyRelationship.cpp
@@ -56,11 +56,15 @@ int PyRelationship::init(PyRelationship* self, PyObject* 
args, PyObject*) {
 }
 
 PyObject* PyRelationship::getName(PyRelationship* self, PyObject*) {
+  PYTHON_METHOD_BEGIN
   return object::returnReference(self->relationship_.getName());
+  PYTHON_METHOD_END
 }
 
 PyObject* PyRelationship::getDescription(PyRelationship* self, PyObject*) {
+  PYTHON_METHOD_BEGIN
   return object::returnReference(self->relationship_.getDescription());
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyRelationship::typeObject() {
diff --git a/extensions/python/types/PySSLContextService.cpp 
b/extensions/python/types/PySSLContextService.cpp
index be73b8f1d..faf9a2774 100644
--- a/extensions/python/types/PySSLContextService.cpp
+++ b/extensions/python/types/PySSLContextService.cpp
@@ -58,39 +58,47 @@ int PySSLContextService::init(PySSLContextService* self, 
PyObject* args, PyObjec
 }
 
 PyObject* PySSLContextService::getCertificateFile(PySSLContextService* self, 
PyObject* /*args*/) {
+  PYTHON_METHOD_BEGIN
   auto ssl_context_service = self->ssl_context_service_.lock();
   if (!ssl_context_service) {
     PyErr_SetString(PyExc_AttributeError, "tried reading ssl context service 
outside 'on_trigger'");
     return nullptr;
   }
   return 
object::returnReference(ssl_context_service->getCertificateFile().string());
+  PYTHON_METHOD_END
 }
 
 PyObject* PySSLContextService::getPassphrase(PySSLContextService* self, 
PyObject* /*args*/) {
+  PYTHON_METHOD_BEGIN
   auto ssl_context_service = self->ssl_context_service_.lock();
   if (!ssl_context_service) {
     PyErr_SetString(PyExc_AttributeError, "tried reading ssl context service 
outside 'on_trigger'");
     return nullptr;
   }
   return object::returnReference(ssl_context_service->getPassphrase());
+  PYTHON_METHOD_END
 }
 
 PyObject* PySSLContextService::getPrivateKeyFile(PySSLContextService* self, 
PyObject* /*args*/) {
+  PYTHON_METHOD_BEGIN
   auto ssl_context_service = self->ssl_context_service_.lock();
   if (!ssl_context_service) {
     PyErr_SetString(PyExc_AttributeError, "tried reading ssl context service 
outside 'on_trigger'");
     return nullptr;
   }
   return 
object::returnReference(ssl_context_service->getPrivateKeyFile().string());
+  PYTHON_METHOD_END
 }
 
 PyObject* PySSLContextService::getCACertificate(PySSLContextService* self, 
PyObject* /*args*/) {
+  PYTHON_METHOD_BEGIN
   auto ssl_context_service = self->ssl_context_service_.lock();
   if (!ssl_context_service) {
     PyErr_SetString(PyExc_AttributeError, "tried reading ssl context service 
outside 'on_trigger'");
     return nullptr;
   }
   return 
object::returnReference(ssl_context_service->getCACertificate().string());
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PySSLContextService::typeObject() {
diff --git a/extensions/python/types/PyScriptFlowFile.cpp 
b/extensions/python/types/PyScriptFlowFile.cpp
index 832e09419..c22399f2d 100644
--- a/extensions/python/types/PyScriptFlowFile.cpp
+++ b/extensions/python/types/PyScriptFlowFile.cpp
@@ -63,6 +63,7 @@ int PyScriptFlowFile::init(PyScriptFlowFile* self, PyObject* 
args, PyObject*) {
 }
 
 PyObject* PyScriptFlowFile::getAttribute(PyScriptFlowFile* self, PyObject* 
args) {
+  PYTHON_METHOD_BEGIN
   auto flow_file = self->script_flow_file_.lock();
   if (!flow_file) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -74,9 +75,11 @@ PyObject* PyScriptFlowFile::getAttribute(PyScriptFlowFile* 
self, PyObject* args)
     return nullptr;
   }
   return 
object::returnReference(flow_file->getAttribute(attribute).value_or(""));
+  PYTHON_METHOD_END
 }
 
 PyObject* PyScriptFlowFile::addAttribute(PyScriptFlowFile* self, PyObject* 
args) {
+  PYTHON_METHOD_BEGIN
   auto flow_file = self->script_flow_file_.lock();
   if (!flow_file) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -90,9 +93,11 @@ PyObject* PyScriptFlowFile::addAttribute(PyScriptFlowFile* 
self, PyObject* args)
   }
 
   return object::returnReference(flow_file->addAttribute(key, 
std::string(value)));
+  PYTHON_METHOD_END
 }
 
 PyObject* PyScriptFlowFile::updateAttribute(PyScriptFlowFile* self, PyObject* 
args) {
+  PYTHON_METHOD_BEGIN
   auto flow_file = self->script_flow_file_.lock();
   if (!flow_file) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -106,9 +111,11 @@ PyObject* 
PyScriptFlowFile::updateAttribute(PyScriptFlowFile* self, PyObject* ar
   }
 
   return object::returnReference(flow_file->updateAttribute(key, 
std::string(value)));
+  PYTHON_METHOD_END
 }
 
 PyObject* PyScriptFlowFile::removeAttribute(PyScriptFlowFile* self, PyObject* 
args) {
+  PYTHON_METHOD_BEGIN
   auto flow_file = self->script_flow_file_.lock();
   if (!flow_file) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -120,9 +127,11 @@ PyObject* 
PyScriptFlowFile::removeAttribute(PyScriptFlowFile* self, PyObject* ar
     return nullptr;
   }
   return object::returnReference(flow_file->removeAttribute(attribute));
+  PYTHON_METHOD_END
 }
 
 PyObject* PyScriptFlowFile::setAttribute(PyScriptFlowFile* self, PyObject* 
args) {
+  PYTHON_METHOD_BEGIN
   auto flow_file = self->script_flow_file_.lock();
   if (!flow_file) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -137,9 +146,11 @@ PyObject* PyScriptFlowFile::setAttribute(PyScriptFlowFile* 
self, PyObject* args)
 
   flow_file->setAttribute(key, value);
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyScriptFlowFile::getSize(PyScriptFlowFile* self, PyObject* 
/*args*/) {
+  PYTHON_METHOD_BEGIN
   auto flow_file = self->script_flow_file_.lock();
   if (!flow_file) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -147,9 +158,11 @@ PyObject* PyScriptFlowFile::getSize(PyScriptFlowFile* 
self, PyObject* /*args*/)
   }
 
   return object::returnReference(flow_file->getSize());
+  PYTHON_METHOD_END
 }
 
 PyObject* PyScriptFlowFile::getAttributes(PyScriptFlowFile* self, PyObject* 
/*args*/) {
+  PYTHON_METHOD_BEGIN
   auto flow_file = self->script_flow_file_.lock();
   if (!flow_file) {
     PyErr_SetString(PyExc_AttributeError, "tried reading FlowFile outside 
'on_trigger'");
@@ -162,6 +175,7 @@ PyObject* PyScriptFlowFile::getAttributes(PyScriptFlowFile* 
self, PyObject* /*ar
   }
 
   return object::returnReference(attributes);
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyScriptFlowFile::typeObject() {
diff --git a/extensions/python/types/PyStateManager.cpp 
b/extensions/python/types/PyStateManager.cpp
index 0b0993a68..bf0f3adb4 100644
--- a/extensions/python/types/PyStateManager.cpp
+++ b/extensions/python/types/PyStateManager.cpp
@@ -58,6 +58,7 @@ int PyStateManager::init(PyStateManager* self, PyObject* 
args, PyObject*) {
 }
 
 PyObject* PyStateManager::set(PyStateManager* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   if (!self->state_manager_) {
     PyErr_SetString(PyExc_AttributeError, "tried reading state manager outside 
'on_trigger'");
     return nullptr;
@@ -76,9 +77,11 @@ PyObject* PyStateManager::set(PyStateManager* self, 
PyObject* args) {
   }
 
   return object::returnReference(self->state_manager_->set(cpp_state));
+  PYTHON_METHOD_END
 }
 
 PyObject* PyStateManager::get(PyStateManager* self, PyObject*) {
+  PYTHON_METHOD_BEGIN
   if (!self->state_manager_) {
     PyErr_SetString(PyExc_AttributeError, "tried reading state manager outside 
'on_trigger'");
     return nullptr;
@@ -92,9 +95,11 @@ PyObject* PyStateManager::get(PyStateManager* self, 
PyObject*) {
   } else {
     Py_RETURN_NONE;
   }
+  PYTHON_METHOD_END
 }
 
 PyObject* PyStateManager::clear(PyStateManager* self, PyObject* /*args*/) {
+  PYTHON_METHOD_BEGIN
   if (!self->state_manager_) {
     PyErr_SetString(PyExc_AttributeError, "tried reading state manager outside 
'on_trigger'");
     return nullptr;
@@ -102,9 +107,11 @@ PyObject* PyStateManager::clear(PyStateManager* self, 
PyObject* /*args*/) {
 
   self->state_manager_->clear();
   Py_RETURN_NONE;
+  PYTHON_METHOD_END
 }
 
 PyObject* PyStateManager::replace(PyStateManager* self, PyObject* args) {
+  PYTHON_METHOD_BEGIN
   if (!self->state_manager_) {
     PyErr_SetString(PyExc_AttributeError, "tried reading state manager outside 
'on_trigger'");
     return nullptr;
@@ -141,6 +148,7 @@ PyObject* PyStateManager::replace(PyStateManager* self, 
PyObject* args) {
   }
 
   return object::returnReference(self->state_manager_->set(new_cpp_state));
+  PYTHON_METHOD_END
 }
 
 PyTypeObject* PyStateManager::typeObject() {

Reply via email to