Unable to catch exception!

I use swig to transfer a class from a C ++ library using python. It works in general, but there is an exception that is thrown from the library, and I cannot catch it in the swig interface, so it just drops the python application!

The PyMonitor.cc class describes the swig interface for the desired Monitor class. The monitor constructor throws an exception if it fails to connect. I would like to handle this exception in PyMonitor, for example:

PyMonitor.cc:

#include "Monitor.h" // ... bool PyMonitor::connect() { try { _monitor = new Monitor(_host, _calibration); } catch (...) { printf("oops!\n"); } } // ... 

However, the connect () method never gets an exception, I just get the error message "terminate called after throwing ...", and the program terminates.

I don’t know too much about swig, but it seems to me that this is all excellent with C ++, and the exception should extend to the connect () method before killing the program.

Any thoughts?

+4
source share
3 answers

You must forward exceptions to Python if you want to parse them. See SWIG Documentation . To forward exceptions, you only need to add the code to the SWIG interface file (.i). Basically, it could be anywhere in the .i file.

All exception types must be specified here, and SWIG only catches the listed exception types (in this case std :: runtime_error, std :: invalid_argument, std :: out_of_range), all other exceptions fall as unknown exceptions (and, thus, are sent correctly !).

 // Handle standard exceptions. // NOTE: needs to be before the %import! %include "exception.i" %exception { try { $action } catch (const std::runtime_error& e) { SWIG_exception(SWIG_RuntimeError, e.what()); } catch (const std::invalid_argument& e) { SWIG_exception(SWIG_ValueError, e.what()); } catch (const std::out_of_range& e) { SWIG_exception(SWIG_IndexError, e.what()); } catch (...) { SWIG_exception(SWIG_RuntimeError, "unknown exception"); } } 
+4
source

I am not familiar with swig or using C ++ and Python together, but if it is under the recent version of Microsoft Visual C ++, then the Monitor class probably throws a C-structured exception rather than a C ++ typed exception. C structured exceptions are not caught by C ++ exception handlers, even catch(...) .

If so, you can use the __try/__except keywords (instead of try/catch ) or use the _set_se_translator function to convert a structured C exception to a C ++ type exception.

(Older versions of MSVC ++ handle C structural exceptions as C ++ int types and fall into C ++ handlers, if I remember correctly.)

If it is not under Microsoft Visual C ++, then I am not sure how this could happen.

EDIT: Since you are saying that this is not MSVC, is it possible that something else catches the exception (and terminates the program) before your code receives it, or maybe there is something in your catch block that throws another exception? Without any details that you can work with, these are the only cases I can think of that can cause these symptoms.

+1
source

It is possible that a function called directly or indirectly by the constructor monitor violates its exception specification and does not allow std::bad_exception . If you have not replaced the standard function to catch this, then this will explain the behavior that you see.

To test this hypothesis, you can try defining your own handler:

 void my_unexpected() { std::cerr << "Bad things have happened!\n"; std::terminate(); } bool PyMonitor::connect() { std::set_unexpected( my_unexpected ); try { _monitor = new Monitor(_host, _calibration); } catch (...) { printf("oops!\n"); } } 

If you get "Bad Things!" error message, then you have confirmed that this is so, but unfortunately, there may not be so many that you can do. If you're lucky, you can throw an exception from my_unexpected , which is allowed by the function exception specification, which currently fails, but in any case, your unexpected handler cannot end normally. He must quit or otherwise terminate.

To fix this, you really need to enter the called code and either fix it so that the exception is not violated, either by fixing the specification itself, or by fixing the code so that it does not throw an exception that is expected.

Another possibility is that when unpacking the stack, an exception is thrown due to the creation of the original exception. This will also lead to termination of the process. In this case, although you can replace the standard termination function, you have no option but to interrupt the program. The completion handler is not allowed to throw or return, it must interrupt the program.

+1
source

All Articles