fix(sentry): ignore postMessage clone noise (#373)
## Summary - filter browser postMessage DataCloneError noise before Sentry send - add focused classifier tests ## Tests - npm test -- resources/js/lib/sentry.test.ts - npm run types *(fails: existing repo-wide TypeScript errors, including missing Wayfinder generated modules)* Fixes PHP-LARAVEL-1M
This commit is contained in:
parent
718cfa9e8f
commit
6335287765
|
|
@ -20,6 +20,7 @@ import { SyncProvider } from './contexts/sync-context';
|
|||
import { initializeTheme } from './hooks/use-appearance';
|
||||
import { initializeChartColorScheme } from './hooks/use-chart-color-scheme';
|
||||
import { initializePostHog } from './lib/posthog';
|
||||
import { isPostMessageDataCloneNoise } from './lib/sentry';
|
||||
import type { SharedData } from './types';
|
||||
import { setTranslations } from './utils/i18n';
|
||||
|
||||
|
|
@ -29,6 +30,13 @@ Sentry.init({
|
|||
integrations: [],
|
||||
tracesSampleRate: 0,
|
||||
sendDefaultPii: true,
|
||||
beforeSend(event) {
|
||||
if (isPostMessageDataCloneNoise(event)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return event;
|
||||
},
|
||||
enabled:
|
||||
import.meta.env.PROD && Boolean(import.meta.env.SENTRY_LARAVEL_DSN),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
import type { Event } from '@sentry/react';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { isPostMessageDataCloneNoise } from './sentry';
|
||||
|
||||
describe('isPostMessageDataCloneNoise', () => {
|
||||
it('drops browser postMessage DataCloneError noise', () => {
|
||||
const event: Event = {
|
||||
exception: {
|
||||
values: [
|
||||
{
|
||||
type: 'DataCloneError',
|
||||
value: 'The object can not be cloned.',
|
||||
stacktrace: {
|
||||
frames: [
|
||||
{
|
||||
function: 'Window.postMessage',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
expect(isPostMessageDataCloneNoise(event)).toBe(true);
|
||||
});
|
||||
|
||||
it('keeps other DataCloneError events without postMessage frames', () => {
|
||||
const event: Event = {
|
||||
exception: {
|
||||
values: [
|
||||
{
|
||||
type: 'DataCloneError',
|
||||
value: 'The object can not be cloned.',
|
||||
stacktrace: {
|
||||
frames: [
|
||||
{
|
||||
function: 'structuredClone',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
expect(isPostMessageDataCloneNoise(event)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import type { Event } from '@sentry/react';
|
||||
|
||||
const CLONE_ERROR_MESSAGE_PATTERN =
|
||||
/object (can not|could not|couldn't|can't) be cloned/i;
|
||||
|
||||
export function isPostMessageDataCloneNoise(event: Event): boolean {
|
||||
return (
|
||||
event.exception?.values?.some((exception) => {
|
||||
const exceptionType = exception.type ?? '';
|
||||
const exceptionValue = exception.value ?? '';
|
||||
const frames = exception.stacktrace?.frames ?? [];
|
||||
|
||||
return (
|
||||
exceptionType === 'DataCloneError' &&
|
||||
CLONE_ERROR_MESSAGE_PATTERN.test(exceptionValue) &&
|
||||
frames.some((frame) =>
|
||||
[frame.function, frame.filename, frame.module].some(
|
||||
(value) => value?.includes('postMessage'),
|
||||
),
|
||||
)
|
||||
);
|
||||
}) ?? false
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue