From cb2dc73cac11b563bac607cc5e3fbc4c039fa9e5 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 18 Jun 2026 19:37:16 +0000 Subject: [PATCH 1/3] fix(sentry): suppress optional-integration import errors (Fixes SDK-PYTHON-YY) The SDK's lightweight Sentry trace function reported ModuleNotFoundError exceptions raised while importing optional framework integrations (blaxel.openai, blaxel.livekit, ...) as if they were SDK bugs. These failures are environment issues: the user imported an integration without installing its extra, the extra has a missing transitive dependency, or a stripped/partial install is missing the integration's modules (e.g. 'No module named blaxel.openai.model'). Expand _is_optional_dependency_error to recognize: - import errors for any optional blaxel integration subpackage - import failures of third-party deps raised while loading an optional integration package Genuine SDK import bugs (failures on blaxel.* core modules) are still captured. Adds tests/core/test_sentry.py. Co-authored-by: psinai --- src/blaxel/core/common/sentry.py | 69 ++++++++++++++++++++++-- tests/core/test_sentry.py | 92 ++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 tests/core/test_sentry.py diff --git a/src/blaxel/core/common/sentry.py b/src/blaxel/core/common/sentry.py index d2538820..ff50f778 100644 --- a/src/blaxel/core/common/sentry.py +++ b/src/blaxel/core/common/sentry.py @@ -41,6 +41,29 @@ # Optional dependencies that may not be installed - import errors for these are expected _OPTIONAL_DEPENDENCIES = ("opentelemetry",) +# Optional blaxel framework integration subpackages. Importing any of these +# requires installing the matching extra (e.g. ``pip install blaxel[openai]``). +# When the extra -- or one of its transitive dependencies -- is missing, or when +# the integration files are absent from a stripped/partial install, importing the +# integration raises an ImportError. That is an expected environment issue, not an +# SDK bug, so it must not be reported to Sentry. +_OPTIONAL_INTEGRATION_PACKAGES = ( + "blaxel.langgraph", + "blaxel.llamaindex", + "blaxel.openai", + "blaxel.crewai", + "blaxel.googleadk", + "blaxel.livekit", + "blaxel.pydantic", + "blaxel.telemetry", +) + +# Filesystem fragments used to detect an import error raised while loading one of +# the optional integration packages above (covers both POSIX and Windows paths). +_OPTIONAL_INTEGRATION_PATHS = tuple( + f"blaxel/{pkg.rsplit('.', 1)[-1]}/" for pkg in _OPTIONAL_INTEGRATION_PACKAGES +) + tuple(f"blaxel\\{pkg.rsplit('.', 1)[-1]}\\" for pkg in _OPTIONAL_INTEGRATION_PACKAGES) + # SDK path patterns to identify errors originating from our SDK _SDK_PATTERNS = [ "blaxel/", @@ -191,10 +214,48 @@ def _get_exception_key(exc_type, exc_value, frame) -> str: def _is_optional_dependency_error(exc_type, exc_value) -> bool: - """Check if the exception is an import error for an optional dependency.""" - if exc_type and issubclass(exc_type, ImportError): - msg = str(exc_value).lower() - return any(dep in msg for dep in _OPTIONAL_DEPENDENCIES) + """Check if the exception is an import error that is expected when an optional + integration extra is not installed. + + These are environment issues (the user imported, e.g., ``blaxel.openai`` + without ``pip install blaxel[openai]``, or runs a stripped/partial install + that is missing the integration's modules) rather than SDK defects, so they + should not be reported to Sentry. + """ + if not (exc_type and issubclass(exc_type, ImportError)): + return False + + # Name of the module that could not be imported, when available + # (e.g. "blaxel.openai.model", "agents", "opentelemetry.exporter.otlp"). + missing = getattr(exc_value, "name", None) or "" + + # 1) The optional integration subpackage itself is unavailable -- e.g. a + # stripped/partial install missing ``blaxel/openai/model.py``, surfacing as + # ModuleNotFoundError("No module named 'blaxel.openai.model'"). + if any( + missing == pkg or missing.startswith(f"{pkg}.") for pkg in _OPTIONAL_INTEGRATION_PACKAGES + ): + return True + + # 2) A known optional third-party dependency could not be imported. + msg = str(exc_value).lower() + if any(dep in missing for dep in _OPTIONAL_DEPENDENCIES) or any( + dep in msg for dep in _OPTIONAL_DEPENDENCIES + ): + return True + + # 3) A non-blaxel (third-party) import failed while loading an optional + # integration package -- i.e. the matching extra is not installed. Only + # treat non-blaxel modules this way so that genuine SDK import bugs (which + # fail on a "blaxel.*" module) are still captured. + if missing and not missing.startswith("blaxel"): + tb = getattr(exc_value, "__traceback__", None) + while tb: + filename = tb.tb_frame.f_code.co_filename + if any(path in filename for path in _OPTIONAL_INTEGRATION_PATHS): + return True + tb = tb.tb_next + return False diff --git a/tests/core/test_sentry.py b/tests/core/test_sentry.py new file mode 100644 index 00000000..29025fea --- /dev/null +++ b/tests/core/test_sentry.py @@ -0,0 +1,92 @@ +"""Tests for the lightweight Sentry error filter. + +The SDK installs a trace function (``sys.settrace``) that forwards exceptions +originating from ``site-packages/blaxel`` to Sentry. Import errors that happen +because an optional integration extra is not installed (or because a +stripped/partial install is missing the integration's modules) are environment +issues, not SDK defects, and must be filtered out before reaching Sentry. +""" + +from blaxel.core.common.sentry import _is_optional_dependency_error + + +def _raise_in_file(filename: str, code: str) -> Exception: + """Execute ``code`` as if it lived in ``filename`` and return the exception. + + Using ``compile`` with an explicit filename makes the resulting traceback + contain a frame whose ``co_filename`` is ``filename``, which lets us simulate + an error raised from inside a given package path. + """ + try: + exec(compile(code, filename, "exec"), {}) + except Exception as e: # noqa: BLE001 - we want the raised exception object + return e + raise AssertionError("code did not raise") + + +class TestIsOptionalDependencyError: + """Cover the import-error classification used to suppress Sentry noise.""" + + def test_missing_integration_submodule_is_optional(self): + """The exact production symptom: a stripped install missing model.py. + + ``from .model import *`` in ``blaxel/openai/__init__.py`` raises + ``ModuleNotFoundError: No module named 'blaxel.openai.model'``. + """ + exc = ModuleNotFoundError( + "No module named 'blaxel.openai.model'", name="blaxel.openai.model" + ) + assert _is_optional_dependency_error(type(exc), exc) is True + + def test_missing_livekit_submodule_is_optional(self): + exc = ModuleNotFoundError( + "No module named 'blaxel.livekit.model'", name="blaxel.livekit.model" + ) + assert _is_optional_dependency_error(type(exc), exc) is True + + def test_each_optional_integration_package_is_covered(self): + for pkg in ( + "blaxel.langgraph", + "blaxel.llamaindex", + "blaxel.openai", + "blaxel.crewai", + "blaxel.googleadk", + "blaxel.livekit", + "blaxel.pydantic", + "blaxel.telemetry", + ): + exc = ModuleNotFoundError(f"No module named '{pkg}.model'", name=f"{pkg}.model") + assert _is_optional_dependency_error(type(exc), exc) is True, pkg + + def test_opentelemetry_dependency_is_optional(self): + """Existing behavior: opentelemetry import errors are still suppressed.""" + exc = ModuleNotFoundError("No module named 'opentelemetry'", name="opentelemetry") + assert _is_optional_dependency_error(type(exc), exc) is True + + def test_missing_third_party_dep_while_loading_integration_is_optional(self): + """A missing extra dep (e.g. ``agents`` for blaxel[openai]) is expected.""" + exc = _raise_in_file( + "/usr/lib/python3.12/site-packages/blaxel/openai/model.py", + "raise ModuleNotFoundError(\"No module named 'agents'\", name='agents')", + ) + assert _is_optional_dependency_error(type(exc), exc) is True + + def test_missing_third_party_dep_outside_integration_is_not_optional(self): + """A third-party import failure outside any optional integration (e.g. a + genuine missing core dependency) must still be reported.""" + exc = _raise_in_file( + "/usr/lib/python3.12/site-packages/blaxel/core/common/settings.py", + "raise ModuleNotFoundError(\"No module named 'httpx'\", name='httpx')", + ) + assert _is_optional_dependency_error(type(exc), exc) is False + + def test_core_module_import_error_is_not_optional(self): + """A genuine SDK bug failing on a ``blaxel.*`` core module is captured.""" + exc = ModuleNotFoundError( + "No module named 'blaxel.core.missing'", name="blaxel.core.missing" + ) + assert _is_optional_dependency_error(type(exc), exc) is False + + def test_non_import_error_is_not_optional(self): + exc = ValueError("not an import error") + assert _is_optional_dependency_error(type(exc), exc) is False From e7ea3192fb9158dcaca859a092805e2a3cd70499 Mon Sep 17 00:00:00 2001 From: mstolarzblaxelai Date: Mon, 22 Jun 2026 19:12:01 -0700 Subject: [PATCH 2/3] fix(sentry): suppress wrapped optional integration import errors --- src/blaxel/core/common/sentry.py | 38 ++++++++++++++++++++++++-------- tests/core/test_sentry.py | 19 ++++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/blaxel/core/common/sentry.py b/src/blaxel/core/common/sentry.py index ff50f778..1f911069 100644 --- a/src/blaxel/core/common/sentry.py +++ b/src/blaxel/core/common/sentry.py @@ -213,7 +213,18 @@ def _get_exception_key(exc_type, exc_value, frame) -> str: return f"{exc_name}:{exc_msg}:{origin}" -def _is_optional_dependency_error(exc_type, exc_value) -> bool: +def _has_optional_integration_frame(exc_value) -> bool: + """Check whether an exception traceback passed through an integration module.""" + tb = getattr(exc_value, "__traceback__", None) + while tb: + filename = tb.tb_frame.f_code.co_filename + if any(path in filename for path in _OPTIONAL_INTEGRATION_PATHS): + return True + tb = tb.tb_next + return False + + +def _is_optional_dependency_error(exc_type, exc_value, seen: set[int] | None = None) -> bool: """Check if the exception is an import error that is expected when an optional integration extra is not installed. @@ -225,6 +236,13 @@ def _is_optional_dependency_error(exc_type, exc_value) -> bool: if not (exc_type and issubclass(exc_type, ImportError)): return False + if seen is None: + seen = set() + exc_id = id(exc_value) + if exc_id in seen: + return False + seen.add(exc_id) + # Name of the module that could not be imported, when available # (e.g. "blaxel.openai.model", "agents", "opentelemetry.exporter.otlp"). missing = getattr(exc_value, "name", None) or "" @@ -244,17 +262,19 @@ def _is_optional_dependency_error(exc_type, exc_value) -> bool: ): return True - # 3) A non-blaxel (third-party) import failed while loading an optional + # 3) Optional integration import guards wrap the original import failure in + # a friendly ImportError with no module name. Suppress that wrapper when + # its explicit cause is already known optional-import noise. + cause = getattr(exc_value, "__cause__", None) + if isinstance(cause, ImportError) and _is_optional_dependency_error(type(cause), cause, seen): + return True + + # 4) A non-blaxel (third-party) import failed while loading an optional # integration package -- i.e. the matching extra is not installed. Only # treat non-blaxel modules this way so that genuine SDK import bugs (which # fail on a "blaxel.*" module) are still captured. - if missing and not missing.startswith("blaxel"): - tb = getattr(exc_value, "__traceback__", None) - while tb: - filename = tb.tb_frame.f_code.co_filename - if any(path in filename for path in _OPTIONAL_INTEGRATION_PATHS): - return True - tb = tb.tb_next + if missing and not missing.startswith("blaxel") and _has_optional_integration_frame(exc_value): + return True return False diff --git a/tests/core/test_sentry.py b/tests/core/test_sentry.py index 29025fea..65a50ed1 100644 --- a/tests/core/test_sentry.py +++ b/tests/core/test_sentry.py @@ -71,6 +71,25 @@ def test_missing_third_party_dep_while_loading_integration_is_optional(self): ) assert _is_optional_dependency_error(type(exc), exc) is True + def test_wrapped_integration_import_guard_error_is_optional(self): + """The friendly optional-extra guard from blaxel.openai stays quiet.""" + exc = _raise_in_file( + "/usr/lib/python3.12/site-packages/blaxel/openai/__init__.py", + """ +try: + raise ModuleNotFoundError( + "No module named 'blaxel.openai.model'", + name="blaxel.openai.model", + ) +except ImportError as e: + raise ImportError( + "The openai extra dependencies are required to use the OpenAI Agents integration. " + "Install them with: pip install blaxel[openai]" + ) from e +""", + ) + assert _is_optional_dependency_error(type(exc), exc) is True + def test_missing_third_party_dep_outside_integration_is_not_optional(self): """A third-party import failure outside any optional integration (e.g. a genuine missing core dependency) must still be reported.""" From adaf2cfac9b26322396f36ff73f45ba88eae6f05 Mon Sep 17 00:00:00 2001 From: Michael Stolarz Date: Tue, 23 Jun 2026 15:34:30 -0700 Subject: [PATCH 3/3] fix(sentry): keep optional integration internals reportable --- src/blaxel/core/common/sentry.py | 36 +++++++++++++---- tests/core/test_sentry.py | 69 +++++++++++++++++--------------- 2 files changed, 66 insertions(+), 39 deletions(-) diff --git a/src/blaxel/core/common/sentry.py b/src/blaxel/core/common/sentry.py index 1f911069..9c718ced 100644 --- a/src/blaxel/core/common/sentry.py +++ b/src/blaxel/core/common/sentry.py @@ -58,6 +58,17 @@ "blaxel.telemetry", ) +_OPTIONAL_INTEGRATION_ENTRYPOINT_MODULES = { + "blaxel.langgraph": ("model", "tools"), + "blaxel.llamaindex": ("model", "tools"), + "blaxel.openai": ("model", "tools"), + "blaxel.crewai": ("model", "tools"), + "blaxel.googleadk": ("model", "tools"), + "blaxel.livekit": ("model", "tools"), + "blaxel.pydantic": ("model", "tools"), + "blaxel.telemetry": ("exporters", "instrumentation", "log", "manager", "span"), +} + # Filesystem fragments used to detect an import error raised while loading one of # the optional integration packages above (covers both POSIX and Windows paths). _OPTIONAL_INTEGRATION_PATHS = tuple( @@ -216,7 +227,7 @@ def _get_exception_key(exc_type, exc_value, frame) -> str: def _has_optional_integration_frame(exc_value) -> bool: """Check whether an exception traceback passed through an integration module.""" tb = getattr(exc_value, "__traceback__", None) - while tb: + while tb is not None: filename = tb.tb_frame.f_code.co_filename if any(path in filename for path in _OPTIONAL_INTEGRATION_PATHS): return True @@ -224,6 +235,17 @@ def _has_optional_integration_frame(exc_value) -> bool: return False +def _is_optional_integration_entrypoint_missing(missing: str) -> bool: + """Check whether the missing module is a public optional integration entrypoint.""" + if missing in _OPTIONAL_INTEGRATION_PACKAGES: + return True + + for package, entrypoints in _OPTIONAL_INTEGRATION_ENTRYPOINT_MODULES.items(): + if any(missing == f"{package}.{entrypoint}" for entrypoint in entrypoints): + return True + return False + + def _is_optional_dependency_error(exc_type, exc_value, seen: set[int] | None = None) -> bool: """Check if the exception is an import error that is expected when an optional integration extra is not installed. @@ -247,12 +269,12 @@ def _is_optional_dependency_error(exc_type, exc_value, seen: set[int] | None = N # (e.g. "blaxel.openai.model", "agents", "opentelemetry.exporter.otlp"). missing = getattr(exc_value, "name", None) or "" - # 1) The optional integration subpackage itself is unavailable -- e.g. a - # stripped/partial install missing ``blaxel/openai/model.py``, surfacing as - # ModuleNotFoundError("No module named 'blaxel.openai.model'"). - if any( - missing == pkg or missing.startswith(f"{pkg}.") for pkg in _OPTIONAL_INTEGRATION_PACKAGES - ): + # 1) A public optional integration entrypoint itself is unavailable -- e.g. + # a stripped/partial install missing ``blaxel/openai/model.py``, + # surfacing as ModuleNotFoundError("No module named 'blaxel.openai.model'"). + # Do not suppress deeper ``blaxel..*`` misses: those may be + # real SDK packaging or internal import bugs and should still reach Sentry. + if _is_optional_integration_entrypoint_missing(missing): return True # 2) A known optional third-party dependency could not be imported. diff --git a/tests/core/test_sentry.py b/tests/core/test_sentry.py index 65a50ed1..ca1a6aec 100644 --- a/tests/core/test_sentry.py +++ b/tests/core/test_sentry.py @@ -7,16 +7,14 @@ issues, not SDK defects, and must be filtered out before reaching Sentry. """ -from blaxel.core.common.sentry import _is_optional_dependency_error +from blaxel.core.common.sentry import ( + _OPTIONAL_INTEGRATION_ENTRYPOINT_MODULES, + _is_optional_dependency_error, +) def _raise_in_file(filename: str, code: str) -> Exception: - """Execute ``code`` as if it lived in ``filename`` and return the exception. - - Using ``compile`` with an explicit filename makes the resulting traceback - contain a frame whose ``co_filename`` is ``filename``, which lets us simulate - an error raised from inside a given package path. - """ + """Execute ``code`` as if it lived in ``filename`` and return the exception.""" try: exec(compile(code, filename, "exec"), {}) except Exception as e: # noqa: BLE001 - we want the raised exception object @@ -45,19 +43,17 @@ def test_missing_livekit_submodule_is_optional(self): assert _is_optional_dependency_error(type(exc), exc) is True def test_each_optional_integration_package_is_covered(self): - for pkg in ( - "blaxel.langgraph", - "blaxel.llamaindex", - "blaxel.openai", - "blaxel.crewai", - "blaxel.googleadk", - "blaxel.livekit", - "blaxel.pydantic", - "blaxel.telemetry", - ): - exc = ModuleNotFoundError(f"No module named '{pkg}.model'", name=f"{pkg}.model") + for pkg in _OPTIONAL_INTEGRATION_ENTRYPOINT_MODULES: + exc = ModuleNotFoundError(f"No module named '{pkg}'", name=pkg) assert _is_optional_dependency_error(type(exc), exc) is True, pkg + def test_each_optional_integration_entrypoint_module_is_covered(self): + for pkg, entrypoints in _OPTIONAL_INTEGRATION_ENTRYPOINT_MODULES.items(): + for entrypoint in entrypoints: + missing = f"{pkg}.{entrypoint}" + exc = ModuleNotFoundError(f"No module named '{missing}'", name=missing) + assert _is_optional_dependency_error(type(exc), exc) is True, missing + def test_opentelemetry_dependency_is_optional(self): """Existing behavior: opentelemetry import errors are still suppressed.""" exc = ModuleNotFoundError("No module named 'opentelemetry'", name="opentelemetry") @@ -71,23 +67,26 @@ def test_missing_third_party_dep_while_loading_integration_is_optional(self): ) assert _is_optional_dependency_error(type(exc), exc) is True + def test_missing_nested_blaxel_module_inside_integration_is_not_optional(self): + """Internal integration packaging/import bugs must still reach Sentry.""" + exc = ModuleNotFoundError( + "No module named 'blaxel.pydantic.custom.gemni'", + name="blaxel.pydantic.custom.gemni", + ) + assert _is_optional_dependency_error(ModuleNotFoundError, exc) is False + def test_wrapped_integration_import_guard_error_is_optional(self): """The friendly optional-extra guard from blaxel.openai stays quiet.""" - exc = _raise_in_file( - "/usr/lib/python3.12/site-packages/blaxel/openai/__init__.py", - """ -try: - raise ModuleNotFoundError( - "No module named 'blaxel.openai.model'", - name="blaxel.openai.model", - ) -except ImportError as e: - raise ImportError( - "The openai extra dependencies are required to use the OpenAI Agents integration. " - "Install them with: pip install blaxel[openai]" - ) from e -""", + cause = ModuleNotFoundError( + "No module named 'blaxel.openai.model'", + name="blaxel.openai.model", ) + exc = ImportError( + "The openai extra dependencies are required to use the OpenAI Agents integration. " + "Install them with: pip install blaxel[openai]" + ) + exc.__cause__ = cause + assert _is_optional_dependency_error(type(exc), exc) is True def test_missing_third_party_dep_outside_integration_is_not_optional(self): @@ -109,3 +108,9 @@ def test_core_module_import_error_is_not_optional(self): def test_non_import_error_is_not_optional(self): exc = ValueError("not an import error") assert _is_optional_dependency_error(type(exc), exc) is False + + def test_circular_import_error_cause_is_not_optional(self): + exc = ImportError("wrapped import failed") + exc.__cause__ = exc + + assert _is_optional_dependency_error(type(exc), exc) is False