| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Importing datajoint installed a global sys.excepthook that routed every uncaught exception in the host process through datajoint's logger. Combined with LevelAwareFormatter overriding format() without rendering exc_info, this reduced every uncaught exception to a contentless '[ERROR]: Uncaught exception' line, discarding the type, message, and traceback -- strictly worse than Python's default handler. - Remove the sys.excepthook installation. A library must not change how unrelated exceptions surface in the importing process; uncaught exceptions now fall through to Python's default handler (full traceback to stderr). - Harden LevelAwareFormatter to append exc_info/stack_info like the base logging.Formatter, so internal logger.exception()/exc_info=... calls never silently drop tracebacks. - Add regression tests.
There was a problem hiding this comment.
LGTM.
Two small non-blocking suggestions:
Formatter tests only exercise WARNING/ERROR levels. exc_info/stack_info handling is appended after the level branches, so it applies uniformly at runtime — but a pytest.parametrize on level across INFO, JOBS, WARNING, ERROR would catch a future regression that adds an early return message inside the JOBS or INFO branch.
Out of scope, follow-up thought: logging.py:17 still does logging.Logger.jobs = jobs — same architectural pattern as the excepthook you're removing (library patching global state at import time). A DataJointLogger(logging.Logger) subclass would be the polite version, but separate PR.
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Fixes #1516.
Problem
Importing datajoint installed a process-wide sys.excepthook as an import side effect, routing every uncaught exception in the host process — DataJoint-related or not — through DataJoint's logger. Combined with LevelAwareFormatter overriding format() without rendering exc_info, every uncaught exception collapsed to a contentless line:
with no type, message, or traceback — strictly worse than Python's default handler, which would have printed the full traceback for free.
History (this is a regression, not the original design)
The hook was originally non-lossy: it inlined the exception message (Uncaught exception: {exc_value}) and rendered a full traceback under DJ_LOG_LEVEL=DEBUG via the stdlib formatter. Two later changes compounded into the silent-discard behavior:
Change
The centralized datajoint logger and its handler/level config are unchanged — only the process-global excepthook is removed.
Compatibility
Behavior change worth a release note: fatal uncaught tracebacks now print to stderr (Python's default handler) rather than as a single line on stdout. This is the correct destination for a crash, and restores the full type/message/traceback that the previous hook discarded.