Files
insights-js/packages/react-native/test/error-tracking-internal-errors.spec.ts
zeekay ec6f6b50c1 chore: kill ALL posthog — zero refs, zero filenames (1452 -> 0)
We own the ingestion server (hanzoai/insights: Django + rust/capture + nodejs
plugin) AND this SDK, so there is no external wire contract to preserve. The
server is already 100% posthog-free; this SDK was the last laggard.

- $last_posthog_reset -> $last_insights_reset. This FIXES A LIVE MISMATCH: the
  server taxonomy (insights/taxonomy/taxonomy.py, insights/insightsql/ai.py)
  already expected the insights form while the SDK emitted the posthog form.
- __PosthogExtensions__ -> __InsightsExtensions__; all PostHog/posthog/POSTHOG
  identifiers -> Insights/insights/INSIGHTS (src, tests, playground, playwright,
  scripts, rrweb subpackages, package.json keywords).
- Hosts: DEFAULT_PLUGIN_HOST + DEFAULT_NUXT_HOST + the core host default pointed
  at PostHog's cloud (us.i.posthog.com) — a real bug. All -> insights.hanzo.ai.
- Removed the us-assets/eu-assets CDN split in getRemoteConfig (PostHog-specific;
  Hanzo serves remote config from the same host) — it had degenerated to a no-op.
- Fixed generate-docs writing to a stray references/@hanzo/ subdir.
- Renamed the 3 posthog-named test files; dropped 58MB of stale reference
  snapshots named for upstream posthog versions we never shipped (they are
  generated output — references/ is now gitignored).

Verified: typecheck errors 42 (HEAD) -> 18 (all pre-existing test-mock
looseness); types package 0; every package.json valid with @hanzo/* names.
Guard: grep -rioE 'posthog' packages ... | wc -l  => 0
2026-07-16 09:09:18 -07:00

97 lines
4.0 KiB
TypeScript

import { ErrorTracking } from '../src/error-tracking'
// Mock the utils to prevent actual global handler registration
jest.mock('../src/error-tracking/utils', () => ({
trackUncaughtExceptions: jest.fn(),
trackUnhandledRejections: jest.fn(),
trackConsole: jest.fn(),
}))
jest.mock('../src/utils', () => ({
isHermes: jest.fn(() => false),
getRemoteConfigBool: jest.requireActual('../src/utils').getRemoteConfigBool,
}))
// Mock core's guard so handler tests can simulate "this is a network error" without
// spinning up a real Insights to produce a genuine instance. The guard itself is
// verified against a real core instance in error-tracking-internal-errors.integration.spec.ts.
jest.mock('@hanzo/insights-core', () => ({
...jest.requireActual('@hanzo/insights-core'),
isInsightsFetchNetworkError: jest.fn(),
}))
import { isInsightsFetchNetworkError } from '@hanzo/insights-core'
import { trackUncaughtExceptions, trackUnhandledRejections, trackConsole } from '../src/error-tracking/utils'
import { createMockLogger, createMockInsights } from './test-utils'
const mockInsights = createMockInsights()
const mockLogger = createMockLogger()
describe('ErrorTracking filters Insights internal network errors', () => {
beforeEach(() => {
jest.clearAllMocks()
;(isInsightsFetchNetworkError as jest.Mock).mockReturnValue(false)
})
it('does not capture a network error from the uncaught exception handler', () => {
;(isInsightsFetchNetworkError as jest.Mock).mockReturnValue(true)
new ErrorTracking(mockInsights, { autocapture: true }, mockLogger as any)
const handler = (trackUncaughtExceptions as jest.Mock).mock.calls[0][0]
handler(new Error('network'), false)
expect(mockInsights.captureException).not.toHaveBeenCalled()
})
it('does not capture a network error from the unhandled rejection handler', () => {
;(isInsightsFetchNetworkError as jest.Mock).mockReturnValue(true)
new ErrorTracking(mockInsights, { autocapture: { unhandledRejections: true } }, mockLogger as any)
const handler = (trackUnhandledRejections as jest.Mock).mock.calls[0][0]
handler(new Error('network'))
expect(mockInsights.captureException).not.toHaveBeenCalled()
})
it('still captures ordinary application errors from the uncaught exception handler', () => {
new ErrorTracking(mockInsights, { autocapture: true }, mockLogger as any)
const handler = (trackUncaughtExceptions as jest.Mock).mock.calls[0][0]
handler(new Error('boom'), false)
expect(mockInsights.captureException).toHaveBeenCalledTimes(1)
})
it('tags a fatal uncaught exception with $exception_level so captureException flushes to disk', () => {
new ErrorTracking(mockInsights, { autocapture: true }, mockLogger as any)
const handler = (trackUncaughtExceptions as jest.Mock).mock.calls[0][0]
handler(new Error('boom'), true)
// captureException drains storage to disk when the exception is fatal, so
// the handler must mark fatal crashes via $exception_level.
const [, additionalProperties] = (mockInsights.captureException as jest.Mock).mock.calls[0]
expect(additionalProperties.$exception_level).toBe('fatal')
})
it('does not tag a non-fatal uncaught exception as fatal', () => {
new ErrorTracking(mockInsights, { autocapture: true }, mockLogger as any)
const handler = (trackUncaughtExceptions as jest.Mock).mock.calls[0][0]
handler(new Error('boom'), false)
const [, additionalProperties] = (mockInsights.captureException as jest.Mock).mock.calls[0]
expect(additionalProperties.$exception_level).toBeUndefined()
})
it('does not filter the console handler (console is left untouched)', () => {
;(isInsightsFetchNetworkError as jest.Mock).mockReturnValue(true)
new ErrorTracking(mockInsights, { autocapture: { console: ['error'] } }, mockLogger as any)
const consoleHandler = (trackConsole as jest.Mock).mock.calls[0][1]
consoleHandler(new Error('network'), false)
expect(mockInsights.captureException).toHaveBeenCalledTimes(1)
})
})