I am not entirely happy with the current design. In particular I don't like the fact that it requires user registered exception translators to always catch all exceptions. If they forget, it breaks the exception translation chain and goes immediately to the default translator. This can in particular be a problem when exception translators are registered by multiple different (potentially external) packages. I have now added an alternative design on a separate branch (tickets/DM-6591-alternative).
This design makes the default handing into just another exception translator which is always tried last. With this design user registered translators are no longer required to always catch all exceptions (which they may forget to do, breaking the exception translation chain). Instead they should only catch those exceptions they actually translate, leaving the rest to the next registered translator.
A downside of this design is that the exception handling code in pybind11 itself is perhaps less readable.
Although the current code is already marked as reviewed, I still think it is important to think about it a bit more. Especially since it will be hard to change once it is upstream. So Jim Bosch if you have time, please have a look and tell me what you think.
Initial attempt ready for review at https://github.com/lsst-dm/pybind11-1/pull/1. I expect we will need to iterate over the design a bit, since we probably cannot change it easily once (if) it is accepted upstream.
Current design is quite bare bones, but offers a great degree of flexibility. We may want to reduce boilerplate a bit by adding some convenience functions. But we also may choose not to.