Suppress Windows DLL hard-error dialog on incompatible plugin load#185
Merged
Conversation
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
nicoddemus
commented
Jun 24, 2026
45452f6 to
02e4633
Compare
BeneBr
approved these changes
Jun 24, 2026
81e2b4f to
02e4633
Compare
Documents how to set up the virtualenv, run type checking, run tests, build C++ artifacts, and regenerate file regression snapshots. Also ignore the .claude/ session directory.
73959fd to
0460a54
Compare
The build task only knew VS 2017 and VS 2019 Enterprise paths; add the VS 2019 BuildTools path so 'inv build' works on machines that have BuildTools installed instead of the full IDE. pybind11 was not found by CMake because no CMAKE_PREFIX_PATH was set; pass it from the pybind11 Python package so the binding target builds correctly with the active virtualenv. Move the build/artifacts sys.path injection from tox's PYTHONPATH setenv into an autouse pytest fixture, so the .pyd is found when running pytest directly outside of tox.
When a plugin DLL has unresolved imports (e.g. a conflicting bundled dependency), Windows would raise a modal hard-error dialog during LoadLibrary before any code could react to the failure. This change suppresses that dialog by setting SEM_FAILCRITICALERRORS via SetThreadErrorMode around every DLL load — both in the Python ctypes path (discovery) and in the generated C++ HookCaller path (hook caller construction). Load failures now surface as a new typed exception (SharedLibraryLoadError) on the Python side, and as a human-readable RuntimeError (via FormatMessageA) on the C++ side, rather than blocking dialogs. Plugin discovery is also made resilient: a single failing plugin no longer aborts enumeration of all others. The new get_plugins_available_and_failures() method returns successful plugins alongside a list of PluginLoadFailure records that callers can use to report the specific reason to the user. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
50dc09d to
6dd2187
Compare
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.
When a plugin DLL has unresolved imports (e.g. a conflicting bundled dependency), Windows would raise a modal hard-error dialog during LoadLibrary before any code could react to the failure.
This change suppresses that dialog and now surface a new typed exception (SharedLibraryLoadError) on the Python side, and as a human-readable RuntimeError (via FormatMessageA) on the C++ side, rather than blocking dialogs.
Plugin discovery is also made resilient: a single failing plugin no longer aborts enumeration of all others. The new get_plugins_available_and_failures() method returns successful plugins alongside a list of PluginLoadFailure records that callers can use to report the specific reason to the user.