PR #293 · pramaan-io/pramaan-functions · merged 2026-06-10
Two silent leaks in the WS observability path
Stale correlation ID in the next request; X-Ray span lost to lowercase
Both naive fixes pass tests — both die in prod.
The fix — Set the tag, reset the tag; read the header in any case it comes.
sequenceDiagram autonumber participant req as WS request participant h as handler participant f as finally participant c as header clerk req->>h: set_correlation_id → token h->>h: work (may throw) h->>f: control falls through f-->>h: reset_correlation_id(token) req->>c: headers arrive mixed-case c->>c: get(): case-insensitive compare c->>c: keys(): original spelling preserved
| Method | in → out | what it does |
|---|---|---|
set_correlation_id | (value) → Token[str | None] | writes the request's ID into the ContextVar and returns the reset token |
reset_correlation_id | (token) → None | consumes that token in finally to wipe the slot and kill cross-invocation bleed |
_CaseInsensitiveDictGetter | (class) | reads header keys case-insensitively at compare time without mutating the carrier dict |
get | (carrier, key) → list[str] | None | returns the trace value whether the caller sent Traceparent, TRACEPARENT, or any case |
Vendored trace wrapper with case-insensitive getter for mixed-case propagator keys; TODO tracks deletion once upstream layers it in.
| new class | signature |
|---|---|
_CaseInsensitiveDictGetter | (class) |
get | (carrier, key) → list[str] | None |
keys | (carrier) → list[str] |
Adds set and reset helpers for the correlation ContextVar so the WS Lambda handler can return the token in finally.
| new method | signature |
|---|---|
set_correlation_id | (value) → Token[str | None] |
reset_correlation_id | (token) → None |