1Exceptions
2##########
3
4Built-in C++ to Python exception translation
5============================================
6
7When Python calls C++ code through pybind11, pybind11 provides a C++ exception handler
8that will trap C++ exceptions, translate them to the corresponding Python exception,
9and raise them so that Python code can handle them.
10
11pybind11 defines translations for ``std::exception`` and its standard
12subclasses, and several special exception classes that translate to specific
13Python exceptions. Note that these are not actually Python exceptions, so they
14cannot be examined using the Python C API. Instead, they are pure C++ objects
15that pybind11 will translate the corresponding Python exception when they arrive
16at its exception handler.
17
18.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
19
20+--------------------------------------+--------------------------------------+
21|  Exception thrown by C++             |  Translated to Python exception type |
22+======================================+======================================+
23| :class:`std::exception`              | ``RuntimeError``                     |
24+--------------------------------------+--------------------------------------+
25| :class:`std::bad_alloc`              | ``MemoryError``                      |
26+--------------------------------------+--------------------------------------+
27| :class:`std::domain_error`           | ``ValueError``                       |
28+--------------------------------------+--------------------------------------+
29| :class:`std::invalid_argument`       | ``ValueError``                       |
30+--------------------------------------+--------------------------------------+
31| :class:`std::length_error`           | ``ValueError``                       |
32+--------------------------------------+--------------------------------------+
33| :class:`std::out_of_range`           | ``IndexError``                       |
34+--------------------------------------+--------------------------------------+
35| :class:`std::range_error`            | ``ValueError``                       |
36+--------------------------------------+--------------------------------------+
37| :class:`std::overflow_error`         | ``OverflowError``                    |
38+--------------------------------------+--------------------------------------+
39| :class:`pybind11::stop_iteration`    | ``StopIteration`` (used to implement |
40|                                      | custom iterators)                    |
41+--------------------------------------+--------------------------------------+
42| :class:`pybind11::index_error`       | ``IndexError`` (used to indicate out |
43|                                      | of bounds access in ``__getitem__``, |
44|                                      | ``__setitem__``, etc.)               |
45+--------------------------------------+--------------------------------------+
46| :class:`pybind11::key_error`         | ``KeyError`` (used to indicate out   |
47|                                      | of bounds access in ``__getitem__``, |
48|                                      | ``__setitem__`` in dict-like         |
49|                                      | objects, etc.)                       |
50+--------------------------------------+--------------------------------------+
51| :class:`pybind11::value_error`       | ``ValueError`` (used to indicate     |
52|                                      | wrong value passed in                |
53|                                      | ``container.remove(...)``)           |
54+--------------------------------------+--------------------------------------+
55| :class:`pybind11::type_error`        | ``TypeError``                        |
56+--------------------------------------+--------------------------------------+
57| :class:`pybind11::buffer_error`      | ``BufferError``                      |
58+--------------------------------------+--------------------------------------+
59| :class:`pybind11::import_error`      | ``import_error``                     |
60+--------------------------------------+--------------------------------------+
61| Any other exception                  | ``RuntimeError``                     |
62+--------------------------------------+--------------------------------------+
63
64Exception translation is not bidirectional. That is, *catching* the C++
65exceptions defined above above will not trap exceptions that originate from
66Python. For that, catch :class:`pybind11::error_already_set`. See :ref:`below
67<handling_python_exceptions_cpp>` for further details.
68
69There is also a special exception :class:`cast_error` that is thrown by
70:func:`handle::call` when the input arguments cannot be converted to Python
71objects.
72
73Registering custom translators
74==============================
75
76If the default exception conversion policy described above is insufficient,
77pybind11 also provides support for registering custom exception translators.
78To register a simple exception conversion that translates a C++ exception into
79a new Python exception using the C++ exception's ``what()`` method, a helper
80function is available:
81
82.. code-block:: cpp
83
84    py::register_exception<CppExp>(module, "PyExp");
85
86This call creates a Python exception class with the name ``PyExp`` in the given
87module and automatically converts any encountered exceptions of type ``CppExp``
88into Python exceptions of type ``PyExp``.
89
90It is possible to specify base class for the exception using the third
91parameter, a `handle`:
92
93.. code-block:: cpp
94
95    py::register_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
96
97Then `PyExp` can be caught both as `PyExp` and `RuntimeError`.
98
99The class objects of the built-in Python exceptions are listed in the Python
100documentation on `Standard Exceptions <https://docs.python.org/3/c-api/exceptions.html#standard-exceptions>`_.
101The default base class is `PyExc_Exception`.
102
103When more advanced exception translation is needed, the function
104``py::register_exception_translator(translator)`` can be used to register
105functions that can translate arbitrary exception types (and which may include
106additional logic to do so).  The function takes a stateless callable (e.g.  a
107function pointer or a lambda function without captured variables) with the call
108signature ``void(std::exception_ptr)``.
109
110When a C++ exception is thrown, the registered exception translators are tried
111in reverse order of registration (i.e. the last registered translator gets the
112first shot at handling the exception).
113
114Inside the translator, ``std::rethrow_exception`` should be used within
115a try block to re-throw the exception.  One or more catch clauses to catch
116the appropriate exceptions should then be used with each clause using
117``PyErr_SetString`` to set a Python exception or ``ex(string)`` to set
118the python exception to a custom exception type (see below).
119
120To declare a custom Python exception type, declare a ``py::exception`` variable
121and use this in the associated exception translator (note: it is often useful
122to make this a static declaration when using it inside a lambda expression
123without requiring capturing).
124
125The following example demonstrates this for a hypothetical exception classes
126``MyCustomException`` and ``OtherException``: the first is translated to a
127custom python exception ``MyCustomError``, while the second is translated to a
128standard python RuntimeError:
129
130.. code-block:: cpp
131
132    static py::exception<MyCustomException> exc(m, "MyCustomError");
133    py::register_exception_translator([](std::exception_ptr p) {
134        try {
135            if (p) std::rethrow_exception(p);
136        } catch (const MyCustomException &e) {
137            exc(e.what());
138        } catch (const OtherException &e) {
139            PyErr_SetString(PyExc_RuntimeError, e.what());
140        }
141    });
142
143Multiple exceptions can be handled by a single translator, as shown in the
144example above. If the exception is not caught by the current translator, the
145previously registered one gets a chance.
146
147If none of the registered exception translators is able to handle the
148exception, it is handled by the default converter as described in the previous
149section.
150
151.. seealso::
152
153    The file :file:`tests/test_exceptions.cpp` contains examples
154    of various custom exception translators and custom exception types.
155
156.. note::
157
158    Call either ``PyErr_SetString`` or a custom exception's call
159    operator (``exc(string)``) for every exception caught in a custom exception
160    translator.  Failure to do so will cause Python to crash with ``SystemError:
161    error return without exception set``.
162
163    Exceptions that you do not plan to handle should simply not be caught, or
164    may be explicitly (re-)thrown to delegate it to the other,
165    previously-declared existing exception translators.
166
167.. _handling_python_exceptions_cpp:
168
169Handling exceptions from Python in C++
170======================================
171
172When C++ calls Python functions, such as in a callback function or when
173manipulating Python objects, and Python raises an ``Exception``, pybind11
174converts the Python exception into a C++ exception of type
175:class:`pybind11::error_already_set` whose payload contains a C++ string textual
176summary and the actual Python exception. ``error_already_set`` is used to
177propagate Python exception back to Python (or possibly, handle them in C++).
178
179.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
180
181+--------------------------------------+--------------------------------------+
182|  Exception raised in Python          |  Thrown as C++ exception type        |
183+======================================+======================================+
184| Any Python ``Exception``             | :class:`pybind11::error_already_set` |
185+--------------------------------------+--------------------------------------+
186
187For example:
188
189.. code-block:: cpp
190
191    try {
192        // open("missing.txt", "r")
193        auto file = py::module_::import("io").attr("open")("missing.txt", "r");
194        auto text = file.attr("read")();
195        file.attr("close")();
196    } catch (py::error_already_set &e) {
197        if (e.matches(PyExc_FileNotFoundError)) {
198            py::print("missing.txt not found");
199        } else if (e.matches(PyExc_PermissionError)) {
200            py::print("missing.txt found but not accessible");
201        } else {
202            throw;
203        }
204    }
205
206Note that C++ to Python exception translation does not apply here, since that is
207a method for translating C++ exceptions to Python, not vice versa. The error raised
208from Python is always ``error_already_set``.
209
210This example illustrates this behavior:
211
212.. code-block:: cpp
213
214    try {
215        py::eval("raise ValueError('The Ring')");
216    } catch (py::value_error &boromir) {
217        // Boromir never gets the ring
218        assert(false);
219    } catch (py::error_already_set &frodo) {
220        // Frodo gets the ring
221        py::print("I will take the ring");
222    }
223
224    try {
225        // py::value_error is a request for pybind11 to raise a Python exception
226        throw py::value_error("The ball");
227    } catch (py::error_already_set &cat) {
228        // cat won't catch the ball since
229        // py::value_error is not a Python exception
230        assert(false);
231    } catch (py::value_error &dog) {
232        // dog will catch the ball
233        py::print("Run Spot run");
234        throw;  // Throw it again (pybind11 will raise ValueError)
235    }
236
237Handling errors from the Python C API
238=====================================
239
240Where possible, use :ref:`pybind11 wrappers <wrappers>` instead of calling
241the Python C API directly. When calling the Python C API directly, in
242addition to manually managing reference counts, one must follow the pybind11
243error protocol, which is outlined here.
244
245After calling the Python C API, if Python returns an error,
246``throw py::error_already_set();``, which allows pybind11 to deal with the
247exception and pass it back to the Python interpreter. This includes calls to
248the error setting functions such as ``PyErr_SetString``.
249
250.. code-block:: cpp
251
252    PyErr_SetString(PyExc_TypeError, "C API type error demo");
253    throw py::error_already_set();
254
255    // But it would be easier to simply...
256    throw py::type_error("pybind11 wrapper type error");
257
258Alternately, to ignore the error, call `PyErr_Clear
259<https://docs.python.org/3/c-api/exceptions.html#c.PyErr_Clear>`_.
260
261Any Python error must be thrown or cleared, or Python/pybind11 will be left in
262an invalid state.
263
264.. _unraisable_exceptions:
265
266Handling unraisable exceptions
267==============================
268
269If a Python function invoked from a C++ destructor or any function marked
270``noexcept(true)`` (collectively, "noexcept functions") throws an exception, there
271is no way to propagate the exception, as such functions may not throw.
272Should they throw or fail to catch any exceptions in their call graph,
273the C++ runtime calls ``std::terminate()`` to abort immediately.
274
275Similarly, Python exceptions raised in a class's ``__del__`` method do not
276propagate, but are logged by Python as an unraisable error. In Python 3.8+, a
277`system hook is triggered
278<https://docs.python.org/3/library/sys.html#sys.unraisablehook>`_
279and an auditing event is logged.
280
281Any noexcept function should have a try-catch block that traps
282class:`error_already_set` (or any other exception that can occur). Note that
283pybind11 wrappers around Python exceptions such as
284:class:`pybind11::value_error` are *not* Python exceptions; they are C++
285exceptions that pybind11 catches and converts to Python exceptions. Noexcept
286functions cannot propagate these exceptions either. A useful approach is to
287convert them to Python exceptions and then ``discard_as_unraisable`` as shown
288below.
289
290.. code-block:: cpp
291
292    void nonthrowing_func() noexcept(true) {
293        try {
294            // ...
295        } catch (py::error_already_set &eas) {
296            // Discard the Python error using Python APIs, using the C++ magic
297            // variable __func__. Python already knows the type and value and of the
298            // exception object.
299            eas.discard_as_unraisable(__func__);
300        } catch (const std::exception &e) {
301            // Log and discard C++ exceptions.
302            third_party::log(e);
303        }
304    }
305
306.. versionadded:: 2.6
307