first commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import { test, expect } from "bun:test";
|
||||
import { createContext } from "@wrnexus/core";
|
||||
import { createTracker, type ErrorEvent, type ErrorSink } from "../src/index.ts";
|
||||
|
||||
function collectingSink(): ErrorSink & { events: ErrorEvent[] } {
|
||||
const events: ErrorEvent[] = [];
|
||||
return { name: "collect", events, capture: (e) => void events.push(e) };
|
||||
}
|
||||
|
||||
test("capture fans out to sinks with context + timestamp", async () => {
|
||||
const sink = collectingSink();
|
||||
const tracker = createTracker({ sinks: [sink], now: () => 123 });
|
||||
await tracker.capture(new Error("boom"), { userId: "u1" });
|
||||
expect(sink.events.length).toBe(1);
|
||||
expect(sink.events[0]!.error.message).toBe("boom");
|
||||
expect(sink.events[0]!.context.userId).toBe("u1");
|
||||
expect(sink.events[0]!.timestamp).toBe(123);
|
||||
});
|
||||
|
||||
test("non-Error values are wrapped", async () => {
|
||||
const sink = collectingSink();
|
||||
const tracker = createTracker({ sinks: [sink] });
|
||||
await tracker.capture("just a string");
|
||||
expect(sink.events[0]!.error.message).toBe("just a string");
|
||||
});
|
||||
|
||||
test("beforeSend can scrub or drop events", async () => {
|
||||
const sink = collectingSink();
|
||||
const tracker = createTracker({
|
||||
sinks: [sink],
|
||||
beforeSend: (e) => (e.context.secret ? null : e), // drop events tagged secret
|
||||
});
|
||||
await tracker.capture(new Error("a"), { secret: true });
|
||||
await tracker.capture(new Error("b"));
|
||||
expect(sink.events.map((e) => e.error.message)).toEqual(["b"]);
|
||||
});
|
||||
|
||||
test("middleware captures a thrown request error and re-throws it", async () => {
|
||||
const sink = collectingSink();
|
||||
const tracker = createTracker({ sinks: [sink] });
|
||||
const url = new URL("http://x/api/boom");
|
||||
const ctx = createContext(new Request(url, { method: "POST" }), url);
|
||||
await expect(
|
||||
tracker.middleware()(ctx, () => {
|
||||
throw new Error("downstream");
|
||||
}),
|
||||
).rejects.toThrow("downstream");
|
||||
expect(sink.events[0]!.context).toMatchObject({ method: "POST", path: "/api/boom" });
|
||||
});
|
||||
|
||||
test("a failing sink never breaks capture", async () => {
|
||||
const bad: ErrorSink = {
|
||||
capture: () => {
|
||||
throw new Error("sink down");
|
||||
},
|
||||
};
|
||||
const good = collectingSink();
|
||||
const tracker = createTracker({ sinks: [bad, good] });
|
||||
await tracker.capture(new Error("x")); // must not throw
|
||||
expect(good.events.length).toBe(1);
|
||||
});
|
||||
Reference in New Issue
Block a user