1Exceptions 2########## 3 4Built-in exception translation 5============================== 6 7When C++ code invoked from Python throws an ``std::exception``, it is 8automatically converted into a Python ``Exception``. pybind11 defines multiple 9special exception classes that will map to different types of Python 10exceptions: 11 12.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}| 13 14+--------------------------------------+--------------------------------------+ 15| C++ exception type | Python exception type | 16+======================================+======================================+ 17| :class:`std::exception` | ``RuntimeError`` | 18+--------------------------------------+--------------------------------------+ 19| :class:`std::bad_alloc` | ``MemoryError`` | 20+--------------------------------------+--------------------------------------+ 21| :class:`std::domain_error` | ``ValueError`` | 22+--------------------------------------+--------------------------------------+ 23| :class:`std::invalid_argument` | ``ValueError`` | 24+--------------------------------------+--------------------------------------+ 25| :class:`std::length_error` | ``ValueError`` | 26+--------------------------------------+--------------------------------------+ 27| :class:`std::out_of_range` | ``IndexError`` | 28+--------------------------------------+--------------------------------------+ 29| :class:`std::range_error` | ``ValueError`` | 30+--------------------------------------+--------------------------------------+ 31| :class:`pybind11::stop_iteration` | ``StopIteration`` (used to implement | 32| | custom iterators) | 33+--------------------------------------+--------------------------------------+ 34| :class:`pybind11::index_error` | ``IndexError`` (used to indicate out | 35| | of bounds access in ``__getitem__``, | 36| | ``__setitem__``, etc.) | 37+--------------------------------------+--------------------------------------+ 38| :class:`pybind11::value_error` | ``ValueError`` (used to indicate | 39| | wrong value passed in | 40| | ``container.remove(...)``) | 41+--------------------------------------+--------------------------------------+ 42| :class:`pybind11::key_error` | ``KeyError`` (used to indicate out | 43| | of bounds access in ``__getitem__``, | 44| | ``__setitem__`` in dict-like | 45| | objects, etc.) | 46+--------------------------------------+--------------------------------------+ 47| :class:`pybind11::error_already_set` | Indicates that the Python exception | 48| | flag has already been set via Python | 49| | API calls from C++ code; this C++ | 50| | exception is used to propagate such | 51| | a Python exception back to Python. | 52+--------------------------------------+--------------------------------------+ 53 54When a Python function invoked from C++ throws an exception, it is converted 55into a C++ exception of type :class:`error_already_set` whose string payload 56contains a textual summary. 57 58There is also a special exception :class:`cast_error` that is thrown by 59:func:`handle::call` when the input arguments cannot be converted to Python 60objects. 61 62Registering custom translators 63============================== 64 65If the default exception conversion policy described above is insufficient, 66pybind11 also provides support for registering custom exception translators. 67To register a simple exception conversion that translates a C++ exception into 68a new Python exception using the C++ exception's ``what()`` method, a helper 69function is available: 70 71.. code-block:: cpp 72 73 py::register_exception<CppExp>(module, "PyExp"); 74 75This call creates a Python exception class with the name ``PyExp`` in the given 76module and automatically converts any encountered exceptions of type ``CppExp`` 77into Python exceptions of type ``PyExp``. 78 79When more advanced exception translation is needed, the function 80``py::register_exception_translator(translator)`` can be used to register 81functions that can translate arbitrary exception types (and which may include 82additional logic to do so). The function takes a stateless callable (e.g. a 83function pointer or a lambda function without captured variables) with the call 84signature ``void(std::exception_ptr)``. 85 86When a C++ exception is thrown, the registered exception translators are tried 87in reverse order of registration (i.e. the last registered translator gets the 88first shot at handling the exception). 89 90Inside the translator, ``std::rethrow_exception`` should be used within 91a try block to re-throw the exception. One or more catch clauses to catch 92the appropriate exceptions should then be used with each clause using 93``PyErr_SetString`` to set a Python exception or ``ex(string)`` to set 94the python exception to a custom exception type (see below). 95 96To declare a custom Python exception type, declare a ``py::exception`` variable 97and use this in the associated exception translator (note: it is often useful 98to make this a static declaration when using it inside a lambda expression 99without requiring capturing). 100 101 102The following example demonstrates this for a hypothetical exception classes 103``MyCustomException`` and ``OtherException``: the first is translated to a 104custom python exception ``MyCustomError``, while the second is translated to a 105standard python RuntimeError: 106 107.. code-block:: cpp 108 109 static py::exception<MyCustomException> exc(m, "MyCustomError"); 110 py::register_exception_translator([](std::exception_ptr p) { 111 try { 112 if (p) std::rethrow_exception(p); 113 } catch (const MyCustomException &e) { 114 exc(e.what()); 115 } catch (const OtherException &e) { 116 PyErr_SetString(PyExc_RuntimeError, e.what()); 117 } 118 }); 119 120Multiple exceptions can be handled by a single translator, as shown in the 121example above. If the exception is not caught by the current translator, the 122previously registered one gets a chance. 123 124If none of the registered exception translators is able to handle the 125exception, it is handled by the default converter as described in the previous 126section. 127 128.. seealso:: 129 130 The file :file:`tests/test_exceptions.cpp` contains examples 131 of various custom exception translators and custom exception types. 132 133.. note:: 134 135 You must call either ``PyErr_SetString`` or a custom exception's call 136 operator (``exc(string)``) for every exception caught in a custom exception 137 translator. Failure to do so will cause Python to crash with ``SystemError: 138 error return without exception set``. 139 140 Exceptions that you do not plan to handle should simply not be caught, or 141 may be explicitly (re-)thrown to delegate it to the other, 142 previously-declared existing exception translators. 143