Repository navigation
fix: register exception translator as module-local - #315
Merged
merlimat merged 1 commit intoOct 22, 2026
Merged
Conversation
The global exception translator ended with a catch-all for std::exception, so it intercepted C++ exceptions thrown by other pybind11 modules imported before pulsar (e.g. duckdb) and turned them into RuntimeError, bypassing those modules' own translators. Registering it with register_local_exception_translator limits it to exceptions thrown from _pulsar, leaving other modules' translation intact. Fixes apache#314
StevenReitsma
force-pushed
the
fix/local-exception-translator
branch
from
October 20, 2026 17:40
726b405 to
be947ae
Compare
merlimat
approved these changes
Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note: AI was used to generate this description text.
Fixes #314
Motivation
export_exceptionsregisters a global pybind11 exception translator that ends with acatch (const std::exception&)catch-all. pybind11 tries global translators newest-first, so whenpulsaris imported after another pybind11 extension (e.g.duckdb), this translator handles that module's C++ exceptions and turns them into a plainRuntimeError. The other module's own translator never runs, so code catching e.g.duckdb.CatalogExceptionbreaks, depending on import order.Modifications
Register the translator with
py::register_local_exception_translator(available since pybind11 2.8; this repo uses 3.0.1). Local translators only apply to exceptions thrown from functions bound in_pulsar, and are tried before any global translators, so:PulsarExceptionsubclasses,std::invalid_argument→ValueError, otherstd::exception→RuntimeError).Verifying this change
I did not build
_pulsaritself locally. To check the pybind11 semantics, I built two minimal modules against pybind11 v3.0.1: one mimicking duckdb (a global translator mapping its own C++ exception to a custom Python exception), and one with the same translator body assrc/exceptions.cc. I imported the duckdb-like module first:PulsarExceptionstd::invalid_argumentstd::exceptionregister_exception_translator(before)RuntimeError❌PulsarExceptionValueErrorRuntimeErrorregister_local_exception_translator(after)CatalogException✅PulsarExceptionValueErrorRuntimeErrorThe existing test suite covers the Pulsar-side exception mapping.