{"version":3,"sources":["../../src/telemetry/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { Span } from '@opentelemetry/api';\nimport { SpanStatusCode } from '@opentelemetry/api';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport { type JobContext, runWithJobContext } from '../job.js';\nimport { REDACTED_EXCEPTION_MESSAGE } from './redaction.js';\nimport * as traceTypes from './trace_types.js';\nimport { type RecordExceptionOptions, recordException } from './utils.js';\n\nfunction fakeSpan() {\n  return {\n    addEvent: vi.fn(),\n    isRecording: vi.fn(() => true),\n    recordException: vi.fn(),\n    setAttribute: vi.fn(),\n    setAttributes: vi.fn(),\n    setStatus: vi.fn(),\n  };\n}\n\nfunction captureException(\n  span: ReturnType<typeof fakeSpan>,\n  options?: RecordExceptionOptions,\n): void {\n  const error = new Error('secret transcript');\n  recordException(span as unknown as Span, error, options);\n}\n\ndescribe('recordException', () => {\n  beforeEach(() => {\n    vi.clearAllMocks();\n  });\n\n  it('preserves exception details when redaction is explicitly disabled', () => {\n    const span = fakeSpan();\n\n    captureException(span, { redacted: false });\n\n    expect(span.recordException).toHaveBeenCalledOnce();\n    // `error.type` is the GenAI/HTTP conventions' low-cardinality error identifier\n    expect(span.setAttribute).toHaveBeenCalledWith(traceTypes.ATTR_ERROR_TYPE, 'Error');\n    expect(span.setStatus).toHaveBeenCalledWith({\n      code: SpanStatusCode.ERROR,\n      message: 'secret transcript',\n    });\n    expect(span.setAttributes).toHaveBeenCalledWith({\n      [traceTypes.ATTR_EXCEPTION_TYPE]: 'Error',\n      [traceTypes.ATTR_EXCEPTION_MESSAGE]: 'secret transcript',\n      [traceTypes.ATTR_EXCEPTION_TRACE]: expect.stringContaining('secret transcript'),\n    });\n  });\n\n  it('omits exception details when redaction is explicitly enabled', () => {\n    const span = fakeSpan();\n\n    captureException(span, { redacted: true });\n\n    const attrs = {\n      [traceTypes.ATTR_EXCEPTION_TYPE]: 'Error',\n      [traceTypes.ATTR_EXCEPTION_MESSAGE]: REDACTED_EXCEPTION_MESSAGE,\n    };\n    expect(span.recordException).not.toHaveBeenCalled();\n    expect(span.addEvent).toHaveBeenCalledWith('exception', attrs);\n    expect(span.setStatus).toHaveBeenCalledWith({\n      code: SpanStatusCode.ERROR,\n      message: REDACTED_EXCEPTION_MESSAGE,\n    });\n    expect(span.setAttributes).toHaveBeenCalledWith(attrs);\n    // `error.type` names the error class, never its message, so it survives redaction\n    expect(span.setAttribute).toHaveBeenCalledWith(traceTypes.ATTR_ERROR_TYPE, 'Error');\n    expect(\n      JSON.stringify([\n        span.addEvent.mock.calls,\n        span.setStatus.mock.calls,\n        span.setAttribute.mock.calls,\n        span.setAttributes.mock.calls,\n      ]),\n    ).not.toContain('secret transcript');\n  });\n\n  it('uses the resolved session redaction setting by default', () => {\n    const span = fakeSpan();\n    const context = {\n      job: { enableRedaction: false },\n      _redactionEnabled: true,\n    } as unknown as JobContext;\n\n    runWithJobContext(context, () => captureException(span));\n\n    expect(span.recordException).not.toHaveBeenCalled();\n    expect(span.setAttributes).toHaveBeenCalledWith({\n      [traceTypes.ATTR_EXCEPTION_TYPE]: 'Error',\n      [traceTypes.ATTR_EXCEPTION_MESSAGE]: REDACTED_EXCEPTION_MESSAGE,\n    });\n  });\n\n  it('preserves exception details by default without a job context', () => {\n    const span = fakeSpan();\n\n    captureException(span);\n\n    expect(span.recordException).toHaveBeenCalledOnce();\n  });\n\n  it('allows an explicit false override for resolved redaction', () => {\n    const span = fakeSpan();\n    const context = {\n      _redactionEnabled: true,\n    } as unknown as JobContext;\n\n    runWithJobContext(context, () => captureException(span, { redacted: false }));\n\n    expect(span.recordException).toHaveBeenCalledOnce();\n    expect(span.setStatus).toHaveBeenCalledWith({\n      code: SpanStatusCode.ERROR,\n      message: 'secret transcript',\n    });\n  });\n});\n"],"mappings":"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","names":[]}