Ok. So I wrote a simple boost python application. I put the exception handling code in. Now, as a test, I tried to run (purposely) a python script with a syntax error in it. The application crashes each time (Runtime Error!). How can I change the app so that it handles python script syntax errors without crashing?

Could you give us the offending code and the Traceback? Your explanation is devoid of any information that could allow us to help you.

Help US help you!

Could you give us the offending code and the Traceback? Your explanation is devoid of any information that could allow us to help you.

Help US help you!

I was unsure whether to post this in the C++ or python forums, but here goes:

bool ScriptInterface::run_python_script(const std::string& filename, int argc, char** argv)
{    

	FILE* fp = NULL;    
	bool success = true;    
	std::string logErrors;



	if (PyImport_AppendInittab("dt_embedded_python_ext", initdt_embedded_python_ext) == -1)
	{
		throw runtime_error("could not register module __dt_embedded_python_ext__");
	}     


	Py_Initialize();    

	try{
		
	    object main_module = extract<object>(PyImport_AddModule("__main__"))();
		object main_namespace(main_module.attr("__dict__"));


		fp = fopen(filename.c_str(), "r");     
		if (!fp)
		{
			throw runtime_error(filename + ": " + strerror(errno));
		}       

		
		boost::python::exec_file(filename.c_str(), main_namespace, main_namespace);

	}    
	catch (const exception& e)
	{       
			fprintf(stderr, "Exception caught: %s\n", e.what());
			logErrors = "Exception caught: ";
			logErrors += e.what(); 
			LogMessage((char*)logErrors.c_str());
			success  = false;
	}    

	if (fp)
		fclose(fp);    


	return success;
}

Anyway, as you can see, there is a try catch exception handler in the code. The problem is that it is never executed on a simple python scipt syntax error, as the program crashes immediately after exec is called.

Well, I found that if I use a catch(...) I can trap the error and even keep the app from crashing by using

boost::python::handle_exception();

I am trying to redirect the stderr message from a python script syntax error to a C++ windows app. Now, I need to trap this message somehow. I changed the catch to the following:

catch (...)
 	{       
		 if(PyErr_Occurred())
		 {
			 PyErr_Print();

			 boost::python::object sys(boost::python::handle<>(PyImport_ImportModule("sys")));
			 boost::python::object err = sys.attr("stderr");
			 std::string err_text = boost::python::extract<std::string>(err.attr("getvalue")());
			 logErrors = "Exception caught: ";
			 logErrors += err_text;
			 LogMessage((char*)logErrors.c_str());
			 boost::python::handle_exception();
		 }

		 success  = false;
	}

Now I get a crash when

std::string err_text = boost::python::extract<std::string>(err.attr("getvalue")());

is called. It appears that the "getvalue" is returning a bad pointer or something...this doesn't make sense to me.

May be you could try this

catch (...)
 	{       
		 if(PyErr_Occurred())
		 {
			 PyErr_Print();

			 boost::python::object traceback(boost::python::handle<>(PyImport_ImportModule("traceback")));
			 std::string err_text = boost::python::extract<std::string>(traceback.attr("format_exc")());
			 logErrors = "Exception caught: ";
			 logErrors += err_text;
			 LogMessage((char*)logErrors.c_str());
			 boost::python::handle_exception();
		 }

		 success  = false;
	}

I don't think the sys.stderr.getvalue exists :)

I tried your suggestion. It returns "None" in err_text. This isn't what is returned by the python interpreter if run from the command line.

I don't understand why it is so difficult to get the stderr message text from python...this seems like it should be a really common problem to people running embedded python.

I think I am giving this up. I don't know if there is a way to trap python syntax errors in boost C++, or even in the Python C API. All I get are empty strings or exceptions thrown.

I tried many different methods, but all fail. If anyone has a solution...that would be absolutely brilliant. peace out...

This article has been dead for over six months. Start a new discussion instead.