fix(lib): stop re-subscribing global error listeners on every render

ErrorTrackingProvider wraps the whole app and keyed its window "error" and
"unhandledrejection" listener effect on trackError. trackError is rebuilt on
every render because it closes over posthog, session and pathname, so the two
global listeners were torn down and re-added on every render of the provider,
including on each navigation and session tick. Hold the latest trackError in a
ref and register the listeners once for the provider's lifetime, dispatching
through the ref so reports still use current posthog/session/pathname context.
This commit is contained in:
abhay-codes07 2026-07-22 17:23:27 +05:30
parent 90f709bf8d
commit a60b38d293
No known key found for this signature in database

View file

@ -1,7 +1,7 @@
"use client"
import { usePathname } from "next/navigation"
import { useEffect } from "react"
import { useEffect, useRef } from "react"
import { useSession } from "./auth"
import { usePostHog } from "./posthog"
@ -79,10 +79,19 @@ export function ErrorTrackingProvider({
}) {
const { trackError } = useErrorTracking()
// trackError is a fresh closure every render (it captures posthog, session and
// pathname), so keying the listener effect on it re-subscribed the two global
// window listeners on every render of this app-wide provider. Hold the latest
// trackError in a ref and register the listeners once for the provider's life.
const trackErrorRef = useRef(trackError)
useEffect(() => {
trackErrorRef.current = trackError
}, [trackError])
useEffect(() => {
// Global error handler for unhandled errors
const handleError = (event: ErrorEvent) => {
trackError(event.error, {
trackErrorRef.current(event.error, {
error_type: "global_error",
source: "window_error",
filename: event.filename,
@ -93,7 +102,7 @@ export function ErrorTrackingProvider({
// Global handler for unhandled promise rejections
const handleUnhandledRejection = (event: PromiseRejectionEvent) => {
trackError(event.reason, {
trackErrorRef.current(event.reason, {
error_type: "unhandled_promise_rejection",
source: "promise_rejection",
})
@ -106,7 +115,7 @@ export function ErrorTrackingProvider({
window.removeEventListener("error", handleError)
window.removeEventListener("unhandledrejection", handleUnhandledRejection)
}
}, [trackError])
}, [])
return <>{children}</>
}