Add support for user defined exception translators
diff --git a/docs/advanced.rst b/docs/advanced.rst
index 2a0e268..9ae48b8 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -817,6 +817,8 @@
 in-place constructor. Memory allocation etc. is already take care of beforehand
 within pybind11.
 
+.. _catching_and_throwing_exceptions:
+
 Catching and throwing exceptions
 ================================
 
@@ -869,6 +871,65 @@
 :func:`handle::call` when the input arguments cannot be converted to Python
 objects.
 
+Registering custom exception translators
+========================================
+
+If the default exception conversion policy described
+:ref:`above <catching_and_throwing_exceptions>`
+is insufficient, pybind11 also provides support for registering custom
+exception translators.
+
+The function ``register_exception_translator(translator)`` takes a stateless
+callable (e.g. a function pointer or a lambda function without captured
+variables) with the following call signature: ``void(std::exception_ptr)``.
+
+When a C++ exception is thrown, registered exception translators are tried
+in reverse order of registration (i.e. the last registered translator gets
+a first shot at handling the exception).
+
+Inside the translator, ``std::rethrow_exception`` should be used within
+a try block to re-throw the exception. A catch clause can then use
+``PyErr_SetString`` to set a Python exception as demonstrated
+in :file:`example19.cpp``.
+
+This example also demonstrates how to create custom exception types
+with ``py::exception``.
+
+The following example demonstrates this for a hypothetical exception class
+``MyCustomException``:
+
+.. code-block:: cpp
+
+    py::register_exception_translator([](std::exception_ptr p) {
+        try {
+            if (p) std::rethrow_exception(p);
+        } catch (const MyCustomException &e) {
+            PyErr_SetString(PyExc_RuntimeError, e.what());
+        }
+    });
+
+Multiple exceptions can be handled by a single translator. If the exception is
+not caught by the current translator, the previously registered one gets a
+chance.
+
+If none of the registered exception translators is able to handle the
+exception, it is handled by the default converter as described in the previous
+section.
+
+.. note::
+
+    You must either call ``PyErr_SetString`` for every exception caught in a
+    custom exception translator. Failure to do so will cause Python to crash
+    with ``SystemError: error return without exception set``.
+
+    Exceptions that you do not plan to handle should simply not be caught.
+
+    You may also choose to explicity (re-)throw the exception to delegate it to
+    the other existing exception translators.
+
+    The ``py::exception`` wrapper for creating custom exceptions cannot (yet)
+    be used as a ``py::base``.
+
 .. _opaque:
 
 Treating STL data structures as opaque objects