From 25487f7152b6b80845fded3b81b1e9bb45447ec5 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 14 Apr 2022 14:47:13 +0200 Subject: [PATCH] feat(eventprocessors): Add name field to EventProcessor (#4932) --- packages/browser/src/integrations/dedupe.ts | 7 +++++-- .../core/src/integrations/inboundfilters.ts | 7 +++++-- packages/core/test/mocks/integration.ts | 20 +++++++++++-------- packages/hub/src/scope.ts | 18 +++++++++++++++-- packages/integrations/src/dedupe.ts | 7 +++++-- packages/integrations/src/offline.ts | 9 +++++++-- packages/nextjs/src/index.client.ts | 7 ++++++- packages/nextjs/src/index.server.ts | 12 ++++++----- packages/types/src/eventprocessor.ts | 5 ++++- 9 files changed, 67 insertions(+), 25 deletions(-) diff --git a/packages/browser/src/integrations/dedupe.ts b/packages/browser/src/integrations/dedupe.ts index c486c84c815e..48aa8411f268 100644 --- a/packages/browser/src/integrations/dedupe.ts +++ b/packages/browser/src/integrations/dedupe.ts @@ -24,7 +24,7 @@ export class Dedupe implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((currentEvent: Event) => { + const eventProcessor: EventProcessor = currentEvent => { const self = getCurrentHub().getIntegration(Dedupe); if (self) { // Juuust in case something goes wrong @@ -40,7 +40,10 @@ export class Dedupe implements Integration { return (self._previousEvent = currentEvent); } return currentEvent; - }); + }; + + eventProcessor.id = this.name; + addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index 6151e32e5bbd..0e9dc859a3f8 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -33,7 +33,7 @@ export class InboundFilters implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (processor: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((event: Event) => { + const eventProcess: EventProcessor = (event: Event) => { const hub = getCurrentHub(); if (hub) { const self = hub.getIntegration(InboundFilters); @@ -45,7 +45,10 @@ export class InboundFilters implements Integration { } } return event; - }); + }; + + eventProcess.id = this.name; + addGlobalEventProcessor(eventProcess); } } diff --git a/packages/core/test/mocks/integration.ts b/packages/core/test/mocks/integration.ts index 465fac64576a..8b95b5673af8 100644 --- a/packages/core/test/mocks/integration.ts +++ b/packages/core/test/mocks/integration.ts @@ -1,6 +1,6 @@ import { getCurrentHub } from '@sentry/hub'; import { configureScope } from '@sentry/minimal'; -import { Event, Integration } from '@sentry/types'; +import { Event, EventProcessor, Integration } from '@sentry/types'; export class TestIntegration implements Integration { public static id: string = 'TestIntegration'; @@ -8,14 +8,18 @@ export class TestIntegration implements Integration { public name: string = 'TestIntegration'; public setupOnce(): void { - configureScope(scope => { - scope.addEventProcessor((event: Event) => { - if (!getCurrentHub().getIntegration(TestIntegration)) { - return event; - } + const eventProcessor: EventProcessor = (event: Event) => { + if (!getCurrentHub().getIntegration(TestIntegration)) { + return event; + } + + return null; + }; - return null; - }); + eventProcessor.id = this.name; + + configureScope(scope => { + scope.addEventProcessor(eventProcessor); }); } } diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index 1733cf7f826f..271827519792 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -19,8 +19,16 @@ import { Transaction, User, } from '@sentry/types'; -import { dateTimestampInSeconds, getGlobalSingleton, isPlainObject, isThenable, SyncPromise } from '@sentry/utils'; - +import { + dateTimestampInSeconds, + getGlobalSingleton, + isPlainObject, + isThenable, + logger, + SyncPromise, +} from '@sentry/utils'; + +import { IS_DEBUG_BUILD } from './flags'; import { Session } from './session'; /** @@ -462,6 +470,12 @@ export class Scope implements ScopeInterface { resolve(event); } else { const result = processor({ ...event }, hint) as Event | null; + + IS_DEBUG_BUILD && + processor.id && + result === null && + logger.log(`Event processor "${processor.id}" dropped event`); + if (isThenable(result)) { void result .then(final => this._notifyEventProcessors(processors, final, hint, index + 1).then(resolve)) diff --git a/packages/integrations/src/dedupe.ts b/packages/integrations/src/dedupe.ts index 644f3d41cd62..a29223f6832b 100644 --- a/packages/integrations/src/dedupe.ts +++ b/packages/integrations/src/dedupe.ts @@ -24,7 +24,7 @@ export class Dedupe implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((currentEvent: Event) => { + const eventProcessor: EventProcessor = currentEvent => { const self = getCurrentHub().getIntegration(Dedupe); if (self) { // Juuust in case something goes wrong @@ -40,7 +40,10 @@ export class Dedupe implements Integration { return (self._previousEvent = currentEvent); } return currentEvent; - }); + }; + + eventProcessor.id = this.name; + addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/integrations/src/offline.ts b/packages/integrations/src/offline.ts index 0d2da0841805..78d8ead05dd4 100644 --- a/packages/integrations/src/offline.ts +++ b/packages/integrations/src/offline.ts @@ -80,10 +80,12 @@ export class Offline implements Integration { }); } - addGlobalEventProcessor((event: Event) => { + const eventProcessor: EventProcessor = event => { if (this.hub && this.hub.getIntegration(Offline)) { // cache if we are positively offline if ('navigator' in this.global && 'onLine' in this.global.navigator && !this.global.navigator.onLine) { + IS_DEBUG_BUILD && logger.log('Event dropped due to being a offline - caching instead'); + void this._cacheEvent(event) .then((_event: Event): Promise => this._enforceMaxEvents()) .catch((_error): void => { @@ -96,7 +98,10 @@ export class Offline implements Integration { } return event; - }); + }; + + eventProcessor.id = this.name; + addGlobalEventProcessor(eventProcessor); // if online now, send any events stored in a previous offline session if ('navigator' in this.global && 'onLine' in this.global.navigator && this.global.navigator.onLine) { diff --git a/packages/nextjs/src/index.client.ts b/packages/nextjs/src/index.client.ts index 817f8ad3ca56..05b4dc64a3f3 100644 --- a/packages/nextjs/src/index.client.ts +++ b/packages/nextjs/src/index.client.ts @@ -1,5 +1,6 @@ import { configureScope, init as reactInit, Integrations as BrowserIntegrations } from '@sentry/react'; import { BrowserTracing, defaultRequestInstrumentationOptions } from '@sentry/tracing'; +import { EventProcessor } from '@sentry/types'; import { nextRouterInstrumentation } from './performance/client'; import { buildMetadata } from './utils/metadata'; @@ -42,9 +43,13 @@ export function init(options: NextjsOptions): void { ...options, integrations, }); + configureScope(scope => { scope.setTag('runtime', 'browser'); - scope.addEventProcessor(event => (event.type === 'transaction' && event.transaction === '/404' ? null : event)); + const filterTransactions: EventProcessor = event => + event.type === 'transaction' && event.transaction === '/404' ? null : event; + filterTransactions.id = 'NextClient404Filter'; + scope.addEventProcessor(filterTransactions); }); } diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index 35ef814d97cd..8d34a989264a 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -2,7 +2,7 @@ import { Carrier, getHubFromCarrier, getMainCarrier } from '@sentry/hub'; import { RewriteFrames } from '@sentry/integrations'; import { configureScope, getCurrentHub, init as nodeInit, Integrations } from '@sentry/node'; import { hasTracingEnabled } from '@sentry/tracing'; -import { Event } from '@sentry/types'; +import { EventProcessor } from '@sentry/types'; import { escapeStringForRegex, logger } from '@sentry/utils'; import * as domainModule from 'domain'; import * as path from 'path'; @@ -71,6 +71,12 @@ export function init(options: NextjsOptions): void { nodeInit(options); + const filterTransactions: EventProcessor = event => { + return event.type === 'transaction' && event.transaction === '/404' ? null : event; + }; + + filterTransactions.id = 'NextServer404Filter'; + configureScope(scope => { scope.setTag('runtime', 'node'); if (isVercel) { @@ -131,10 +137,6 @@ function addServerIntegrations(options: NextjsOptions): void { } } -function filterTransactions(event: Event): Event | null { - return event.type === 'transaction' && event.transaction === '/404' ? null : event; -} - export type { SentryWebpackPluginOptions } from './config/types'; export { withSentryConfig } from './config'; export { withSentry } from './utils/withSentry'; diff --git a/packages/types/src/eventprocessor.ts b/packages/types/src/eventprocessor.ts index 13727ae2e797..22bd74f0ab73 100644 --- a/packages/types/src/eventprocessor.ts +++ b/packages/types/src/eventprocessor.ts @@ -6,4 +6,7 @@ import { Event, EventHint } from './event'; * Returning a PromiseLike will work just fine, but better be sure that you know what you are doing. * Event processing will be deferred until your Promise is resolved. */ -export type EventProcessor = (event: Event, hint?: EventHint) => PromiseLike | Event | null; +export interface EventProcessor { + id?: string; // This field can't be named "name" because functions already have this field natively + (event: Event, hint?: EventHint): PromiseLike | Event | null; +}