Files
EpicNext-Cms/src/lib/error-monitor.test.ts
T

57 lines
2.0 KiB
TypeScript

import { mkdtemp, rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { expect, it } from "vitest";
import { createErrorRecord, ErrorStore } from "./error-monitor";
it("redacts secrets in messages, stack and context while retaining a reference", () => {
const r = createErrorRecord(
"server",
"payment.failed",
new Error("https://user:password@host/a?token=abc password=hello"),
{
token: "secret",
path: "/a?session=hidden",
nested: { password: "never" },
},
);
const text = JSON.stringify(r);
for (const secret of ["password@", "token=abc", "hello", "hidden", "never"])
expect(text).not.toContain(secret);
expect(r.id).toBeTruthy();
expect(r.stack).toContain("Error");
});
it("persists across instances and groups repeated errors without losing references", async () => {
const dir = await mkdtemp(path.join(os.tmpdir(), "cms-errors-"));
try {
const store = new ErrorStore(dir);
const a = createErrorRecord("server", "test", new Error("failed"));
await store.append(a);
await store.append({ ...a, id: "second" });
const result = await new ErrorStore(dir).read();
expect(result.records).toHaveLength(2);
expect(result.records[0].fingerprint).toBe(result.records[1].fingerprint);
} finally {
await rm(dir, { recursive: true, force: true });
}
});
it("resolves a group and reopens it when a later occurrence arrives", async () => {
const dir = await mkdtemp(path.join(os.tmpdir(), "cms-errors-"));
try {
const store = new ErrorStore(dir);
const a = createErrorRecord("server", "test", new Error("failed"));
await store.append(a);
await store.resolve(a.fingerprint);
expect((await store.read()).records[0].resolved).toBe(true);
await store.append({
...a,
id: "later",
at: new Date(Date.now() + 1000).toISOString(),
});
expect((await store.read()).records[0].resolved).toBe(false);
await expect(store.resolve("../escape")).rejects.toThrow();
} finally {
await rm(dir, { recursive: true, force: true });
}
});