Skip to content

0.8.4 — OTel partial-install hardening

Choose a tag to compare

@lesnik512 lesnik512 released this 08 Jun 11:21
b95f357

httpware 0.8.4 — OTel partial-install no longer crashes a live request

Patch release. Defensive fix. No API change. Closes the two paired audit findings tracking the OpenTelemetry partial-install hazard.

The gap

httpware's observability layer treats opentelemetry-api as an optional extra. It detects whether the extra is installed via find_spec("opentelemetry") at module load time, then takes the OTel branch in _emit_event only if the flag is True.

Two flaws in that gate let a partial install crash a live request:

  1. opentelemetry is a PEP 420 native namespace package. Any opentelemetry-instrumentation-* package creates the opentelemetry/ directory, so find_spec("opentelemetry") returns a non-None spec even when opentelemetry-api is absent.
  2. The lazy from opentelemetry import trace inside _emit_event was not wrapped in try/except. With the false-positive flag from (1), the import then raised ImportError mid-emit, crashing the middleware calling _emit_eventAsyncRetry, Retry, AsyncBulkhead, Bulkhead — in the middle of a live HTTP request.

The audit's chunk-2 finding named both halves of the hole; this release closes both.

The fix

Two changes:

  • import_checker.is_otel_installed now probes via importlib.metadata.distribution("opentelemetry-api") (inside a try/except PackageNotFoundError block). This checks the package registry directly: True only when the opentelemetry-api distribution is actually installed, regardless of whether some other package created the opentelemetry/ namespace directory. Note: the obvious alternative — find_spec("opentelemetry.trace") — was rejected because CPython resolves submodule probes by importing the parent namespace package, which would have broken the existing transitive-import isolation guarantee enforced by tests/test_optional_extras_isolation.py. The metadata probe has no sys.modules side effects.
  • _emit_event wraps the lazy from opentelemetry import trace in try/except ImportError. On failure (corrupt install, future namespace surprise, monkey-patched sys.modules), emission degrades to log-only — the structured log record fires unconditionally; the OTel add_event call is skipped.

We catch ImportError specifically, not bare Exception. Misconfigured-tracer crashes (RuntimeError, AttributeError out of trace.get_current_span().add_event(...)) still surface; only the install-gate-is-wrong case is in scope.

Upgrade

uv add httpware==0.8.4
# or
pip install -U 'httpware==0.8.4'

No import changes. No API surface changes. No behavior change on the happy path (api package installed and importable). The only observable change is "no longer crashes" on partial installs.