Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 65 additions & 4 deletions src/blaxel/core/common/sentry.py
Original file line number Diff line number Diff line change
Expand Up @@ -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/",
Expand Down Expand Up @@ -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


Expand Down
92 changes: 92 additions & 0 deletions tests/core/test_sentry.py
Original file line number Diff line number Diff line change
@@ -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
Loading