Skip to content
Source
Sign inSign up

safeLog.test.ts

49 lines1.9 KB

1import { describe, expect, it } from "vite-plus/test";
2​
3import { safeErrorLogAttributes } from "./safeLog.ts";
4​
5describe("safeErrorLogAttributes", () => {
6 it("keeps correlation and stack frames without serializing messages or nested causes", () => {
7 const cause = Object.assign(new Error("nested-cause-secret-sentinel"), {
8 traceId: "trace-safe-123",
9 });
10 const error = Object.assign(new Error("outer-error-secret-sentinel", { cause }), {
11 _tag: "ProjectRemovalError",
12 });
13 error.stack = [
14 "ProjectRemovalError: outer-error-secret-sentinel",
15 " at removeProject (https://user:password@example.com/project.ts?token=secret#fragment)",
16 " at loadSettings (http://localhost:5173/src/useSettings.ts?t=1730700000000:162:7)",
17 "removeAll@https://example.com/app.js?token=secret:12:5",
18 ].join("\n");
19​
20 const attributes = safeErrorLogAttributes(error);
21​
22 expect(attributes).toMatchObject({
23 errorType: "error",
24 errorName: "Error",
25 errorTag: "ProjectRemovalError",
26 traceId: "trace-safe-123",
27 stack: [
28 " at removeProject (https://example.com/project.ts)",
29 " at loadSettings (http://localhost:5173/src/useSettings.ts:162:7)",
30 "removeAll@https://example.com/app.js:12:5",
31 ].join("\n"),
32 });
33 const diagnosticText = Object.values(attributes).map(String).join("\n");
34 expect(diagnosticText).not.toContain("outer-error-secret-sentinel");
35 expect(diagnosticText).not.toContain("nested-cause-secret-sentinel");
36 expect(diagnosticText).not.toContain("user:password");
37 expect(diagnosticText).not.toContain("token=secret");
38 });
39​
40 it("does not trust arbitrary object messages or tags", () => {
41 const attributes = safeErrorLogAttributes({
42 _tag: "payload-secret-sentinel",
43 message: "message-secret-sentinel",
44 cause: { traceId: "trace id with unsafe whitespace" },
45 });
46​
47 expect(attributes).toEqual({ errorType: "object" });
48 });
49});