Request Tracing
🔍 How do I trace a single request end-to-end? Every request gets a unique ID that appears in browser network tabs, API logs, and error responses — so you can pinpoint exactly what happened.
What is X-Request-ID?
Section titled “What is X-Request-ID?”Every HTTP request that the Strata frontend sends carries an X-Request-ID header — a UUID generated by the Axios client. The NestJS backend reads this header and attaches it to every log line it writes for that request.
This means you can correlate:
- What the browser sent
- What the backend received and processed
- What error (if any) was returned
The Complete Path
Section titled “The Complete Path”Browser (Axios) ↓ generates: X-Request-ID: 8f3a1b2c-... ↓ sends: GET /api/v1/assets
NestJS RequestIdMiddleware ↓ reads X-Request-ID from header (or generates a new UUID if absent) ↓ attaches to request context
Logger (every log line for this request) [HTTP] [8f3a1b2c-...] GET /assets 200 14ms
Error responses (if any) { "message": "...", "requestId": "8f3a1b2c-..." }
Axios response interceptor ↓ reads X-Request-ID from response headers ↓ includes in ApiError.requestIdHow the Frontend Generates the ID
Section titled “How the Frontend Generates the ID”In front/src/lib/api/client.ts, a request interceptor runs before every Axios request:
client.interceptors.request.use((config) => { if (!config.headers['X-Request-ID']) { config.headers['X-Request-ID'] = crypto.randomUUID(); } return config;});- A new UUID is generated for each request.
- If a custom
X-Request-IDis already set (e.g., for testing), it is preserved. crypto.randomUUID()is a native browser API — no external library needed.
How to See It in the Browser
Section titled “How to See It in the Browser”- Open DevTools → Network tab
- Click any API request to
localhost:3000 - Under Request Headers → look for
X-Request-ID: 8f3a1b2c-... - Under Response Headers → the same ID is echoed back as
x-request-id
If the request failed, the error toast in the UI may also display the request ID.
How to Use It for Debugging
Section titled “How to Use It for Debugging”Filter Docker logs by one request
Section titled “Filter Docker logs by one request”# Find all log lines for a specific requestdocker logs strata-backend 2>&1 | grep "8f3a1b2c-4d5e-6789-abcd-ef0123456789"
# Tail logs live and filter to a request you're watchingdocker logs -f strata-backend 2>&1 | grep "8f3a1b2c"Find errors from the last N minutes
Section titled “Find errors from the last N minutes”# Get recent error log lines with their request IDsdocker logs strata-backend 2>&1 | grep "ERROR" | tail -20Reproduce a production error in dev
Section titled “Reproduce a production error in dev”- User reports: “I got an error — the page said request ID
abc-123” - You search backend logs:
docker logs strata-backend 2>&1 | grep "abc-123" - You see the full request: path, timing, error message, stack trace
What Happens Without the Header
Section titled “What Happens Without the Header”If a request arrives at NestJS without an X-Request-ID header (e.g., from Bruno, curl, or a direct HTTP call), the RequestIdMiddleware generates a fresh UUID automatically. All requests are always traced — the frontend just makes it seamless.
Reference: NestJS Middleware
Section titled “Reference: NestJS Middleware”The middleware lives in backend/src/presentation/middlewares/request-id.middleware.ts. It:
- Reads
req.headers['x-request-id'](case-insensitive) - Falls back to
crypto.randomUUID()if absent - Attaches the ID to
req.requestIdfor downstream use - Sets
res.setHeader('X-Request-ID', id)so the client can read it back