Skip to content

fix: expose Fastify request id in error envelope for incident correlation - #166

Merged
dev-fani merged 1 commit into
fanilabs:mainfrom
Sundayabel222:feat/error-envelope-request-id
Aug 30, 2026
Merged

fix: expose Fastify request id in error envelope for incident correlation#166
dev-fani merged 1 commit into
fanilabs:mainfrom
Sundayabel222:feat/error-envelope-request-id

Conversation

@Sundayabel222

@Sundayabel222 Sundayabel222 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Closes #77
Closes #86
Closes #87
Closes #88

Summary

When a user reports "I got a 500", support currently has nothing to correlate it against. Fastify already generates a request id and embeds it (req.id) in every request log line, but the HTTP error envelope never exposed it.

This PR surfaces that id in every error response shape — { error: { code, message, ... }, requestId } — so a reported error can be matched directly to its request log entry:

{
  "error": { "code": "INTERNAL_ERROR", "message": "An unexpected error occurred" },
  "requestId": "req-2"
}

Changes

  • src/shared/errors/error-handler.ts
    • Added a required requestId to ErrorResponseBody, populated from request.id in all error branches (AppError, ZodError, Fastify-validation, each of the 5 Prisma codes, Fastify 4xx, and the masked 500).
    • Also fixes a latent leak: the handler previously echoed error.details to clients even on 5xx AppErrors (e.g. DB connection strings, RPC payloads). Details on ≥500 responses are now logged server-side but omitted from the client payload. This aligns the handler with what the spec already asserted, and is a security-sensible default.
  • src/shared/errors/error-handler.spec.ts
    • Mock request now carries id: 'req-123'; added assertions that requestId flows through on 5xx, 4xx, and generic-500 paths.
    • Fixed broken test fixtures: the AppError subclasses called super('CODE', message, status, details) — a 4-arg call into a 2-arg constructor — leaving code/statusCode undefined and silently making 5 of the 8 tests fail. They now define real code/statusCode fields. (Pre-existing failure, unrelated to the feature; you can reproduce on main.)

Verification

  • pnpm vitest run src/shared/errors/error-handler.spec.ts → 8/8 passing
  • pnpm exec eslint on both changed files → clean
  • No typecheck errors introduced in the touched files (the repo has unrelated, pre-existing errors in notifications routes, env.test.ts, redact.spec.ts, and the e2e specs that I left untouched).

Notes

  • requestId is the same value Fastify logs as req.id in the request log line, so it's a direct correlation key.
  • No consumer currently depends on 5xx error.details being returned (verified across integration/spec tests).

Closes the incident-correlation gap reported in the issue.

…tion

Add the request id to every error response body so a user reporting a
5xx can share it and support can correlate to the matching request log
line. Also mask 5xx AppError details from client responses (previously
echoed despite the tests asserting otherwise) to avoid leaking internal
DB/RPC details, and repair the spec's AppError fixtures whose constructor
signatures set no code/statusCode.

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Aug 30, 2026

Copy link
Copy Markdown

@Sundayabel222 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@dev-fani
dev-fani merged commit a59d75f into fanilabs:main Aug 30, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants