92 lines
3.1 KiB
TypeScript
92 lines
3.1 KiB
TypeScript
import { describe, it, expect, vi } from "vitest";
|
|
import { recordSpanException } from "../src/v3/otel/utils.js";
|
|
import type { Span } from "@opentelemetry/api";
|
|
|
|
function createMockSpan() {
|
|
return {
|
|
recordException: vi.fn(),
|
|
setStatus: vi.fn(),
|
|
} as unknown as Span & {
|
|
recordException: ReturnType<typeof vi.fn>;
|
|
setStatus: ReturnType<typeof vi.fn>;
|
|
};
|
|
}
|
|
|
|
describe("recordSpanException", () => {
|
|
it("records Error instances with truncated message and stack", () => {
|
|
const span = createMockSpan();
|
|
const error = new Error("x".repeat(5_000));
|
|
recordSpanException(span, error);
|
|
|
|
expect(span.recordException).toHaveBeenCalledTimes(1);
|
|
const recorded = (span.recordException as any).mock.calls[0][0] as Error;
|
|
expect(recorded).toBeInstanceOf(Error);
|
|
expect(recorded.message.length).toBeLessThan(1100);
|
|
});
|
|
|
|
it("records string errors with truncation", () => {
|
|
const span = createMockSpan();
|
|
recordSpanException(span, "x".repeat(10_000));
|
|
|
|
const recorded = (span.recordException as any).mock.calls[0][0] as string;
|
|
expect(typeof recorded).toBe("string");
|
|
expect(recorded.length).toBeLessThan(5_100);
|
|
expect(recorded).toContain("...[truncated]");
|
|
});
|
|
|
|
it("does not throw on circular references", () => {
|
|
const span = createMockSpan();
|
|
const circular: any = { foo: "bar" };
|
|
circular.self = circular;
|
|
|
|
expect(() => recordSpanException(span, circular)).not.toThrow();
|
|
expect(span.recordException).toHaveBeenCalledTimes(1);
|
|
expect(span.setStatus).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("does not throw on BigInt values", () => {
|
|
const span = createMockSpan();
|
|
const error = { count: BigInt(123) };
|
|
|
|
expect(() => recordSpanException(span, error)).not.toThrow();
|
|
expect(span.recordException).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("handles symbol values (JSON.stringify returns undefined)", () => {
|
|
const span = createMockSpan();
|
|
const sym = Symbol("test");
|
|
|
|
expect(() => recordSpanException(span, sym)).not.toThrow();
|
|
expect(span.recordException).toHaveBeenCalledTimes(1);
|
|
const recorded = (span.recordException as any).mock.calls[0][0] as string;
|
|
expect(typeof recorded).toBe("string");
|
|
expect(recorded).toContain("Symbol");
|
|
});
|
|
|
|
it("handles function values (JSON.stringify returns undefined)", () => {
|
|
const span = createMockSpan();
|
|
const fn = () => "test";
|
|
|
|
expect(() => recordSpanException(span, fn)).not.toThrow();
|
|
expect(span.recordException).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("handles undefined (JSON.stringify returns undefined)", () => {
|
|
const span = createMockSpan();
|
|
|
|
expect(() => recordSpanException(span, undefined)).not.toThrow();
|
|
expect(span.recordException).toHaveBeenCalledTimes(1);
|
|
const recorded = (span.recordException as any).mock.calls[0][0] as string;
|
|
expect(typeof recorded).toBe("string");
|
|
});
|
|
|
|
it("always calls setStatus ERROR", () => {
|
|
const span = createMockSpan();
|
|
recordSpanException(span, new Error("test"));
|
|
recordSpanException(span, "string");
|
|
recordSpanException(span, { obj: true });
|
|
|
|
expect(span.setStatus).toHaveBeenCalledTimes(3);
|
|
});
|
|
});
|