diff --git a/backend/src/api/middleware/errors.ts b/backend/src/api/middleware/errors.ts index ffacd0d..655d928 100644 --- a/backend/src/api/middleware/errors.ts +++ b/backend/src/api/middleware/errors.ts @@ -1,8 +1,8 @@ import type { ErrorRequestHandler } from "express"; import { logger } from "../../logger.js"; -export const errorHandler: ErrorRequestHandler = (err, _req, res, _next) => { - logger.error(err, "Unhandled error"); +export const errorHandler: ErrorRequestHandler = (err, req, res, _next) => { + (req.log ?? logger).error(err, "Unhandled error"); res.status(err.statusCode ?? 500).json({ error: err.name ?? "InternalServerError", message: err.message ?? "An unexpected error occurred", diff --git a/backend/src/api/middleware/requestId.ts b/backend/src/api/middleware/requestId.ts new file mode 100644 index 0000000..3e4eee2 --- /dev/null +++ b/backend/src/api/middleware/requestId.ts @@ -0,0 +1,18 @@ +import { randomUUID } from "crypto"; +import type { Request, Response, NextFunction } from "express"; +import { logger } from "../../logger.js"; + +declare module "express-serve-static-core" { + interface Request { + requestId: string; + log: typeof logger; + } +} + +export function requestId(req: Request, res: Response, next: NextFunction) { + const id = randomUUID(); + req.requestId = id; + req.log = logger.child({ requestId: id }); + res.setHeader("X-Request-ID", id); + next(); +} diff --git a/backend/src/app.ts b/backend/src/app.ts index 43267cb..b9feb45 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -11,6 +11,7 @@ import { yieldsRouter } from "./api/routes/yields.js"; import { adminRouter } from "./api/routes/admin.js"; import { webhooksRouter } from "./api/routes/webhooks.js"; import { errorHandler } from "./api/middleware/errors.js"; +import { requestId } from "./api/middleware/requestId.js"; import { publicLimiter, authLimiter } from "./api/middleware/rateLimit.js"; export function createApp(): Express { @@ -26,6 +27,8 @@ export function createApp(): Express { app.use(cors({ origin })); } + app.use(requestId); + app.use("/health", publicLimiter, healthRouter); app.use("/api/v1/vaults", publicLimiter, vaultsRouter); app.use("/api/v1/users", publicLimiter, usersRouter);