Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More information from SWIG::DirectorMethodException #450

Closed
neworderofjamie opened this issue Aug 12, 2021 · 1 comment
Closed

More information from SWIG::DirectorMethodException #450

neworderofjamie opened this issue Aug 12, 2021 · 1 comment

Comments

@neworderofjamie
Copy link
Contributor

neworderofjamie commented Aug 12, 2021

These get thrown (and since #433 caught!) when errors happen in Python callbacks called from C++ using SWIG directors e.g. derived parameter calculation code. However, the code generated by SWIG to throw the exceptions looks like:

PyObject *error = PyErr_Occurred();
if (error) {
  Swig::DirectorMethodException::raise("Error detected when calling 'DerivedParamFunc.__call__'");
}

So the contents of the error i.e. the message is totally ignored (meaning that, until I dug into this I was worried something was really wrong with this code but infact I had just forgotten to import numpy...). Extra code can be monkey-patched into the exception throwing code with (from google):

%feature("director:except") {
    if( $error != NULL ) {
      PyObject *ptype, *pvalue, *ptraceback;
      PyErr_Fetch( &ptype, &pvalue, &ptraceback );
      PyErr_Restore( ptype, pvalue, ptraceback );
      PyErr_Print();
      Py_Exit(1);
    }
  }

which prints out a standard Python error message. However I'm not really sure what all the PyErr_Fetch and PyErr_Restore business does and I'd rather pipe the errors back into an exception message or something but, that is definitely beyond my Python C API understanding (@alexdewar any thoughts as a more experienced Python C API wrangler?)

@alexdewar
Copy link
Collaborator

I think the way to do it would be to convert pvalue to a Python string (which should include the type name, message and stack trace) and then C++-ify that:
https://stackoverflow.com/questions/37684153/convert-exception-error-to-string
https://stackoverflow.com/questions/5356773/python-get-string-representation-of-pyobject

If it turns out to be a faff I guess you could always dig into pybind11 and see what magic they're using.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants