I agreed that the wording on the document page leaves much to be desired. Although "Cython cannot throw C ++ exceptions," a raise_py_error occurs here, which does what we want.
First, define a custom exception class in cython and make a handle to it using the keyword "public"
from cpython.ref cimport PyObject class JMapError(RuntimeError): pass cdef public PyObject* jmaperror = <PyObject*>JMapError
Then write the exception handler (the documents are not very clear, this should be written in C ++ and imported):
#include "Python.h" #include "jmap/cy_utils.H" #include "jmap/errors.H" #include <exception> #include <string> using namespace std; extern PyObject *jmaperror; void raise_py_error() { try { throw; } catch (JMapError& e) { string msg = ::to_string(e.code()) +" "+ e.what(); PyErr_SetString(jmaperror, msg.c_str()); } catch (const std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what() ); } }
Finally, bring the handler in cython using an external block and use it:
cdef extern from "jmap/cy_utils.H": cdef void raise_py_error() void _connect "connect"() except +raise_py_error
Done. Now I see a new exception built with an error code as intended:
JMapError: 520 timed connect failed: Connection refused
source share