diff --git a/src/client/lib/posthog.ts b/src/client/lib/posthog.ts index 2acff78..5298361 100644 --- a/src/client/lib/posthog.ts +++ b/src/client/lib/posthog.ts @@ -20,12 +20,16 @@ type ExceptionEntry = { stacktrace?: { frames?: unknown[] }; }; -// Unactionable exceptions we don't want polluting error tracking. They share +// Unactionable exceptions we don't want polluting error tracking. Most share // the trait of not being our code: browser extensions inject promise rejections // and cross-origin scripts surface as a detail-less "Script error.", while the // global onerror handler synthesizes a stackless "undefined" when it fires // without a real Error object. Real app errors always carry a stack, so the // "undefined" rule is gated on synthetic + no frames to avoid false drops. +// The rest are expected cancellations: TanStack Query throws "CancelledError" +// when a route load is abandoned mid-flight (navigating away), which is normal +// behavior, not a failure. Matched exactly so a real error that merely mentions +// cancellation still gets captured. function isIgnorableException( properties: Record | undefined, ): boolean { @@ -36,6 +40,7 @@ function isIgnorableException( if (value.includes("Object Not Found Matching Id")) return true; if (value === "Script error.") return true; if (value.includes("signal is aborted without reason")) return true; + if (value === "CancelledError") return true; const frames = entry?.stacktrace?.frames; return ( value === "undefined" &&