Skip to content

Commit 0043f8a

Browse files
lesnik512claude
andcommitted
docs(release): draft 0.8.4 notes — OTel partial-install hardening
Two paired defensive fixes (importlib.metadata.distribution probe + try/except ImportError wrap) close the chunk-2 partial-install audit findings. No API change; the only observable behavior change is "no longer crashes" on partial installs. Note: the spec called for find_spec("opentelemetry.trace") as the new probe; release notes reflect what actually shipped (distribution probe, chosen to avoid a sys.modules side-effect that breaks the existing isolation test). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a77cef6 commit 0043f8a

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

planning/releases/0.8.4.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# httpware 0.8.4 — OTel partial-install no longer crashes a live request
2+
3+
**Patch release. Defensive fix. No API change.** Closes the two paired audit findings tracking the OpenTelemetry partial-install hazard.
4+
5+
## The gap
6+
7+
`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.
8+
9+
Two flaws in that gate let a partial install crash a live request:
10+
11+
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.
12+
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_event``AsyncRetry`, `Retry`, `AsyncBulkhead`, `Bulkhead` — in the middle of a live HTTP request.
13+
14+
The audit's [chunk-2 finding](../audit/2026-06-07-deep-audit.md) named both halves of the hole; this release closes both.
15+
16+
## The fix
17+
18+
Two changes:
19+
20+
- `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.
21+
- `_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.
22+
23+
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.
24+
25+
## Upgrade
26+
27+
```bash
28+
uv add httpware==0.8.4
29+
# or
30+
pip install -U 'httpware==0.8.4'
31+
```
32+
33+
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.

0 commit comments

Comments
 (0)