Skip to content

C++ exceptions from backend as Python exceptions #201

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

Open
samir-nasibli opened this issue Oct 29, 2020 · 2 comments
Open

C++ exceptions from backend as Python exceptions #201

samir-nasibli opened this issue Oct 29, 2020 · 2 comments

Comments

@samir-nasibli
Copy link

It would greatly enhance user's experience if C++ exceptions where intercepted and rethrown as Python exceptions.

Detected on review #170

@oleksandr-pavlyk
Copy link
Contributor

Relevant: https://stackoverflow.com/questions/10684983/handling-custom-c-exceptions-in-cython

This is what Cython generates for the line cdef queue* q = new queue():

 try {
    __pyx_t_6 = new cl::sycl::queue();
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 18, __pyx_L1_error)
  }

where

#ifndef __Pyx_CppExn2PyErr
#include <new>
#include <typeinfo>
#include <stdexcept>
#include <ios>
static void __Pyx_CppExn2PyErr() {
  try {
    if (PyErr_Occurred())
      ; // let the latest Python exn pass through and ignore the current one
    else
      throw;
  } catch (const std::bad_alloc& exn) {
    PyErr_SetString(PyExc_MemoryError, exn.what());
  } catch (const std::bad_cast& exn) {
    PyErr_SetString(PyExc_TypeError, exn.what());
  } catch (const std::bad_typeid& exn) {
    PyErr_SetString(PyExc_TypeError, exn.what());
  } catch (const std::domain_error& exn) {
    PyErr_SetString(PyExc_ValueError, exn.what());
  } catch (const std::invalid_argument& exn) {
    PyErr_SetString(PyExc_ValueError, exn.what());
  } catch (const std::ios_base::failure& exn) {
    PyErr_SetString(PyExc_IOError, exn.what());
  } catch (const std::out_of_range& exn) {
    PyErr_SetString(PyExc_IndexError, exn.what());
  } catch (const std::overflow_error& exn) {
    PyErr_SetString(PyExc_OverflowError, exn.what());
  } catch (const std::range_error& exn) {
    PyErr_SetString(PyExc_ArithmeticError, exn.what());
  } catch (const std::underflow_error& exn) {
    PyErr_SetString(PyExc_ArithmeticError, exn.what());
  } catch (const std::exception& exn) {
    PyErr_SetString(PyExc_RuntimeError, exn.what());
  }
  catch (...)
  {
    PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
  }
}
#endif

@shssf
Copy link
Contributor

shssf commented Nov 16, 2020

If you use this approach and call Cython function from another Cython function - exception will be ignored.
Example: DPNP exception functions https://github.com/IntelPython/dpnp/blame/master/dpnp/dpnp_utils.pyx#L113 We used such approach for them and have delete it.

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

No branches or pull requests

3 participants