mirror of
https://github.com/stablyai/orca.git
synced 2026-09-30 08:03:12 +00:00
fix: dispose renderer crash diagnostics hooks (#4216)
This commit is contained in:
@@ -9,12 +9,21 @@ describe('renderer crash diagnostics', () => {
|
||||
let listeners: Map<string, Listener[]>
|
||||
let recordBreadcrumbMock: ReturnType<typeof vi.fn>
|
||||
let setIntervalMock: ReturnType<typeof vi.fn>
|
||||
let clearIntervalMock: ReturnType<typeof vi.fn>
|
||||
let removeEventListenerMock: ReturnType<typeof vi.fn>
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.resetModules()
|
||||
listeners = new Map()
|
||||
recordBreadcrumbMock = vi.fn()
|
||||
setIntervalMock = vi.fn(() => 1)
|
||||
clearIntervalMock = vi.fn()
|
||||
removeEventListenerMock = vi.fn((type: string, listener: Listener) => {
|
||||
listeners.set(
|
||||
type,
|
||||
(listeners.get(type) ?? []).filter((candidate) => candidate !== listener)
|
||||
)
|
||||
})
|
||||
vi.stubGlobal('window', {
|
||||
api: {
|
||||
crashReports: {
|
||||
@@ -26,7 +35,9 @@ describe('renderer crash diagnostics', () => {
|
||||
current.push(listener)
|
||||
listeners.set(type, current)
|
||||
}),
|
||||
removeEventListener: removeEventListenerMock,
|
||||
setInterval: setIntervalMock,
|
||||
clearInterval: clearIntervalMock,
|
||||
performance: {
|
||||
memory: {
|
||||
usedJSHeapSize: 32 * 1024 * 1024,
|
||||
@@ -97,6 +108,18 @@ describe('renderer crash diagnostics', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('disposes global listeners and the memory interval', () => {
|
||||
diagnostics.installRendererCrashDiagnostics()
|
||||
|
||||
diagnostics._disposeRendererCrashDiagnosticsForTests()
|
||||
|
||||
expect(removeEventListenerMock).toHaveBeenCalledWith('error', expect.any(Function))
|
||||
expect(removeEventListenerMock).toHaveBeenCalledWith('unhandledrejection', expect.any(Function))
|
||||
expect(clearIntervalMock).toHaveBeenCalledWith(1)
|
||||
expect(listeners.get('error')).toHaveLength(0)
|
||||
expect(listeners.get('unhandledrejection')).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('does not throw when preload is unavailable', () => {
|
||||
vi.stubGlobal('window', {})
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ type BrowserPerformanceMemory = {
|
||||
}
|
||||
|
||||
let rendererCrashDiagnosticsInstalled = false
|
||||
let rendererMemoryInterval: number | null = null
|
||||
|
||||
export function recordRendererCrashBreadcrumb(
|
||||
name: string,
|
||||
@@ -42,10 +43,36 @@ export function installRendererCrashDiagnostics(): void {
|
||||
|
||||
if (getPerformanceMemory()) {
|
||||
recordRendererMemory('startup')
|
||||
window.setInterval(() => recordRendererMemory('interval'), RENDERER_MEMORY_SAMPLE_INTERVAL_MS)
|
||||
rendererMemoryInterval = window.setInterval(
|
||||
() => recordRendererMemory('interval'),
|
||||
RENDERER_MEMORY_SAMPLE_INTERVAL_MS
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function _disposeRendererCrashDiagnosticsForTests(): void {
|
||||
disposeRendererCrashDiagnostics()
|
||||
}
|
||||
|
||||
function disposeRendererCrashDiagnostics(): void {
|
||||
if (!rendererCrashDiagnosticsInstalled || typeof window === 'undefined') {
|
||||
return
|
||||
}
|
||||
rendererCrashDiagnosticsInstalled = false
|
||||
window.removeEventListener('error', recordRendererError)
|
||||
window.removeEventListener('unhandledrejection', recordRendererUnhandledRejection)
|
||||
if (rendererMemoryInterval !== null) {
|
||||
window.clearInterval(rendererMemoryInterval)
|
||||
rendererMemoryInterval = null
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof import.meta !== 'undefined' && import.meta.hot) {
|
||||
// Why: Vite can replace this module without a full renderer reload. Remove
|
||||
// global diagnostics hooks so dev sessions do not accumulate listeners.
|
||||
import.meta.hot.dispose(disposeRendererCrashDiagnostics)
|
||||
}
|
||||
|
||||
function recordRendererError(event: ErrorEvent): void {
|
||||
recordRendererCrashBreadcrumb(
|
||||
'renderer_error',
|
||||
|
||||
Reference in New Issue
Block a user