import { describe, it, expect, vi } from "vitest"; import { withCapture } from "@/instrumentation/with-capture"; import type { ILogger } from "@/instrumentation/logger.interface"; import { isReported } from "@/instrumentation/reported-flag"; function makeLogger(): ILogger & { captureException: ReturnType } { return { captureException: vi.fn(), captureMessage: vi.fn(), addBreadcrumb: vi.fn(), setUser: vi.fn(), }; } describe("withCapture", () => { it("does not capture on success", async () => { const logger = makeLogger(); const wrapped = withCapture(logger, { layer: "use-case" }, async (x: number) => x + 1); await expect(wrapped(1)).resolves.toBe(2); expect(logger.captureException).not.toHaveBeenCalled(); }); it("captures with tags and re-throws on failure", async () => { const logger = makeLogger(); const err = new Error("boom"); const wrapped = withCapture(logger, { layer: "use-case", name: "blog.x" }, async () => { throw err; }); await expect(wrapped()).rejects.toBe(err); expect(logger.captureException).toHaveBeenCalledTimes(1); expect(logger.captureException).toHaveBeenCalledWith(err, { tags: { layer: "use-case", name: "blog.x" }, }); }); it("marks the error as reported after first capture", async () => { const logger = makeLogger(); const err = new Error("boom"); const wrapped = withCapture(logger, { layer: "use-case" }, async () => { throw err; }); await expect(wrapped()).rejects.toBe(err); expect(isReported(err)).toBe(true); }); it("does NOT capture again when the same error already carries the flag", async () => { const logger = makeLogger(); const err = new Error("boom"); // Simulate an inner layer (repo) having already captured + marked. const inner = withCapture(logger, { layer: "repo" }, async () => { throw err; }); const outer = withCapture(logger, { layer: "use-case" }, () => inner()); await expect(outer()).rejects.toBe(err); // Only the inner layer captured it; outer saw the flag and bailed. expect(logger.captureException).toHaveBeenCalledTimes(1); expect(logger.captureException).toHaveBeenCalledWith(err, { tags: { layer: "repo" }, }); }); });