Skip to content

Commit 916b127

Browse files
committed
Prevent agent from starting twice in edge case
1 parent e4986e3 commit 916b127

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import * as t from "tap";
2+
import { wrap } from "./wrap";
3+
4+
const logs: string[] = [];
5+
wrap(console, "error", function warn() {
6+
return function error(message: string) {
7+
logs.push(message);
8+
};
9+
});
10+
wrap(console, "log", function warn() {
11+
return function log(message: string) {
12+
logs.push(message);
13+
};
14+
});
15+
16+
t.test("it works", async (t) => {
17+
process.env.AIKIDO_DEBUG = "true";
18+
process.env.AIKIDO_BLOCK = "false";
19+
20+
t.same(logs, []);
21+
require("../index");
22+
t.same(logs, [
23+
"AIKIDO: Starting agent v0.0.0...",
24+
"AIKIDO: Dry mode enabled, no requests will be blocked!",
25+
"AIKIDO: No token provided, disabling reporting.",
26+
"AIKIDO: Running in monitoring only mode without reporting to Aikido Cloud. Set AIKIDO_BLOCK=true to enable blocking.",
27+
]);
28+
29+
// Clear logs
30+
logs.length = 0;
31+
32+
// Clear require cache
33+
for (const path in require.cache) {
34+
delete require.cache[path];
35+
}
36+
37+
require("../index");
38+
39+
t.same(logs, [
40+
"AIKIDO: Zen has already been initialized. Please ensure that Zen is imported only once in your application, as importing it multiple times can lead to unexpected behavior.",
41+
]);
42+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const symbol = Symbol.for("zen.nodejs.index.run.once");
2+
3+
export function checkIndexImportGuard(): boolean {
4+
const globalState = globalThis as typeof globalThis & {
5+
[symbol]: boolean;
6+
};
7+
8+
if (globalState[symbol]) {
9+
// eslint-disable-next-line no-console
10+
console.error(
11+
"AIKIDO: Zen has already been initialized. Please ensure that Zen is imported only once in your application, as importing it multiple times can lead to unexpected behavior."
12+
);
13+
14+
return false;
15+
}
16+
17+
globalState[symbol] = true;
18+
return true;
19+
}

library/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import { addHapiMiddleware } from "./middleware/hapi";
1010
import { addFastifyHook } from "./middleware/fastify";
1111
import { addKoaMiddleware } from "./middleware/koa";
1212
import { isESM } from "./helpers/isESM";
13+
import { checkIndexImportGuard } from "./helpers/indexImportGuard";
1314

1415
const supported = isFirewallSupported();
1516
const shouldEnable = shouldEnableFirewall();
17+
const notAlreadyImported = checkIndexImportGuard();
1618

17-
if (supported && shouldEnable) {
19+
if (supported && shouldEnable && notAlreadyImported) {
1820
if (isESM()) {
1921
console.warn(
2022
"AIKIDO: Your application seems to be running in ESM mode. Zen does not support ESM at runtime yet."

0 commit comments

Comments
 (0)