Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading either the Sample or Default database doesn't create a default Agenda Item #2482 #2794

Closed
wants to merge 15 commits into from
Closed
29 changes: 18 additions & 11 deletions src/libraries/requestTracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import cls from "cls-hooked";
// No type defintions available for package 'cls-bluebird'
// @ts-expect-error--ts-ignore
import clsBluebird from "cls-bluebird";
import { customAlphabet } from "nanoid";
import type { NextFunction, Request, Response } from "express";

// Alphabets used in the custom nanoid function
Expand All @@ -12,7 +11,6 @@ const alphabets = "0123456789abcdefghijklmnopqrstuvwxyz";
* Custom nanoid function to generate a unique 10 characters request ID
* using the characters in the alphabets variable.
*/
const nanoid = customAlphabet(alphabets, 10);

/**
* Namespace for request tracing to maintain context across asynchronous operations.
Expand All @@ -32,6 +30,10 @@ export const tracingIdHeaderName = "X-Tracing-Id";
*/
const tracingIdContextKeyName = "tracingId";

const getNanoid: () => Promise<() => string> = async () => {
const { customAlphabet } = await import("nanoid");
return customAlphabet(alphabets, 10);
};
/**
* Sets the tracing ID in the namespace context.
* @param tracingId - The tracing ID to set.
Expand All @@ -58,16 +60,20 @@ export const middleware = () => {
return (req: Request, res: Response, next: NextFunction): void => {
requestTracingNamespace.bindEmitter(req);
requestTracingNamespace.bindEmitter(res);
getNanoid()
.then((nanoid) => {
const tracingId = req.header(tracingIdHeaderName) || nanoid();
req.headers[tracingIdHeaderName] = tracingId;
res.header(tracingIdHeaderName, tracingId);

const tracingId = req.header(tracingIdHeaderName) || nanoid();
// We need to set header to ensure API gateway which proxies request, forwards the header as well
req.headers[tracingIdHeaderName] = tracingId;
res.header(tracingIdHeaderName, tracingId); // Adding tracing ID to response headers

requestTracingNamespace.run(() => {
setTracingId(tracingId);
next();
});
requestTracingNamespace.run(() => {
setTracingId(tracingId);
});
})
.catch((error) => {
next(error);
});
next();
};
};

Expand All @@ -82,6 +88,7 @@ export const trace = async <T>(
tracingId: string,
method: () => T,
): Promise<void> => {
const nanoid = await getNanoid();
await requestTracingNamespace.runAndReturn<T>(() => {
setTracingId(tracingId || nanoid());
return method();
Expand Down
8 changes: 8 additions & 0 deletions tests/libraries/requestTracing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ describe("middleware -> requestContext", () => {
context = requestTracingNamespace.createContext();
requestTracingNamespace.enter(context);
});
it("test requestContext Middleware", () => {
middleware()(
mockRequest as Request,
mockResponse as Response,
nextFunction as NextFunction,
);
expect(nextFunction).toBeCalledTimes(1);
});

it("basic storing and retrieving the key value pair", () => {
requestTracingNamespace.set(tracingIdContextKeyName, "value");
Expand Down
Loading