diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 6468c312bbe1..114ac4a670fe 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -63,6 +63,7 @@ export { convertIntegrationFnToClass, } from './integration'; export { FunctionToString, InboundFilters, LinkedErrors } from './integrations'; +export { applyScopeDataToEvent } from './utils/applyScopeDataToEvent'; export { prepareEvent } from './utils/prepareEvent'; export { createCheckInEnvelope } from './checkin'; export { hasTracingEnabled } from './utils/hasTracingEnabled'; diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts index ae6fe70e3185..599b5c0f8d57 100644 --- a/packages/core/src/scope.ts +++ b/packages/core/src/scope.ts @@ -15,6 +15,7 @@ import type { RequestSession, Scope as ScopeInterface, ScopeContext, + ScopeData, Session, Severity, SeverityLevel, @@ -26,6 +27,7 @@ import { arrayify, dateTimestampInSeconds, isPlainObject, uuid4 } from '@sentry/ import { getGlobalEventProcessors, notifyEventProcessors } from './eventProcessors'; import { updateSession } from './session'; +import { applyScopeDataToEvent } from './utils/applyScopeDataToEvent'; /** * Default value for maximum number of breadcrumbs added to an event. @@ -466,78 +468,65 @@ export class Scope implements ScopeInterface { return this; } + /** @inheritDoc */ + public getScopeData(): ScopeData { + const { + _breadcrumbs, + _attachments, + _contexts, + _tags, + _extra, + _user, + _level, + _fingerprint, + _eventProcessors, + _propagationContext, + _sdkProcessingMetadata, + _transactionName, + _span, + } = this; + + return { + breadcrumbs: _breadcrumbs, + attachments: _attachments, + contexts: _contexts, + tags: _tags, + extra: _extra, + user: _user, + level: _level, + fingerprint: _fingerprint || [], + eventProcessors: _eventProcessors, + propagationContext: _propagationContext, + sdkProcessingMetadata: _sdkProcessingMetadata, + transactionName: _transactionName, + span: _span, + }; + } + /** * Applies data from the scope to the event and runs all event processors on it. * * @param event Event * @param hint Object containing additional information about the original exception, for use by the event processors. * @hidden + * @deprecated Use `applyScopeDataToEvent()` directly */ public applyToEvent( event: Event, hint: EventHint = {}, - additionalEventProcessors?: EventProcessor[], + additionalEventProcessors: EventProcessor[] = [], ): PromiseLike { - if (this._extra && Object.keys(this._extra).length) { - event.extra = { ...this._extra, ...event.extra }; - } - if (this._tags && Object.keys(this._tags).length) { - event.tags = { ...this._tags, ...event.tags }; - } - if (this._user && Object.keys(this._user).length) { - event.user = { ...this._user, ...event.user }; - } - if (this._contexts && Object.keys(this._contexts).length) { - event.contexts = { ...this._contexts, ...event.contexts }; - } - if (this._level) { - event.level = this._level; - } - if (this._transactionName) { - event.transaction = this._transactionName; - } - - // We want to set the trace context for normal events only if there isn't already - // a trace context on the event. There is a product feature in place where we link - // errors with transaction and it relies on that. - if (this._span) { - event.contexts = { trace: this._span.getTraceContext(), ...event.contexts }; - const transaction = this._span.transaction; - if (transaction) { - event.sdkProcessingMetadata = { - dynamicSamplingContext: transaction.getDynamicSamplingContext(), - ...event.sdkProcessingMetadata, - }; - const transactionName = transaction.name; - if (transactionName) { - event.tags = { transaction: transactionName, ...event.tags }; - } - } - } - - this._applyFingerprint(event); - - const scopeBreadcrumbs = this._getBreadcrumbs(); - const breadcrumbs = [...(event.breadcrumbs || []), ...scopeBreadcrumbs]; - event.breadcrumbs = breadcrumbs.length > 0 ? breadcrumbs : undefined; - - event.sdkProcessingMetadata = { - ...event.sdkProcessingMetadata, - ...this._sdkProcessingMetadata, - propagationContext: this._propagationContext, - }; + applyScopeDataToEvent(event, this.getScopeData()); // TODO (v8): Update this order to be: Global > Client > Scope - return notifyEventProcessors( - [ - ...(additionalEventProcessors || []), - // eslint-disable-next-line deprecation/deprecation - ...getGlobalEventProcessors(), - ...this._eventProcessors, - ], - event, - hint, - ); + const eventProcessors: EventProcessor[] = [ + ...additionalEventProcessors, + // eslint-disable-next-line deprecation/deprecation + ...getGlobalEventProcessors(), + ...this._eventProcessors, + ]; + + return notifyEventProcessors(eventProcessors, event, hint); } /** @@ -564,13 +553,6 @@ export class Scope implements ScopeInterface { return this._propagationContext; } - /** - * Get the breadcrumbs for this scope. - */ - protected _getBreadcrumbs(): Breadcrumb[] { - return this._breadcrumbs; - } - /** * This will be called on every set call. */ @@ -586,25 +568,6 @@ export class Scope implements ScopeInterface { this._notifyingListeners = false; } } - - /** - * Applies fingerprint from the scope to the event if there's one, - * uses message if there's one instead or get rid of empty fingerprint - */ - private _applyFingerprint(event: Event): void { - // Make sure it's an array first and we actually have something in place - event.fingerprint = event.fingerprint ? arrayify(event.fingerprint) : []; - - // If we have something on the scope, then merge it with event - if (this._fingerprint) { - event.fingerprint = event.fingerprint.concat(this._fingerprint); - } - - // If we have no data at all, remove empty array default - if (event.fingerprint && !event.fingerprint.length) { - delete event.fingerprint; - } - } } function generatePropagationContext(): PropagationContext { diff --git a/packages/core/src/utils/applyScopeDataToEvent.ts b/packages/core/src/utils/applyScopeDataToEvent.ts new file mode 100644 index 000000000000..cc63e7c26cb6 --- /dev/null +++ b/packages/core/src/utils/applyScopeDataToEvent.ts @@ -0,0 +1,97 @@ +import type { Breadcrumb, Event, PropagationContext, ScopeData, Span } from '@sentry/types'; +import { arrayify } from '@sentry/utils'; + +/** + * Applies data from the scope to the event and runs all event processors on it. + */ +export function applyScopeDataToEvent(event: Event, data: ScopeData): void { + const { fingerprint, span, breadcrumbs, sdkProcessingMetadata, propagationContext } = data; + + // Apply general data + applyDataToEvent(event, data); + + // We want to set the trace context for normal events only if there isn't already + // a trace context on the event. There is a product feature in place where we link + // errors with transaction and it relies on that. + if (span) { + applySpanToEvent(event, span); + } + + applyFingerprintToEvent(event, fingerprint); + applyBreadcrumbsToEvent(event, breadcrumbs); + applySdkMetadataToEvent(event, sdkProcessingMetadata, propagationContext); +} + +function applyDataToEvent(event: Event, data: ScopeData): void { + const { extra, tags, user, contexts, level, transactionName } = data; + + if (extra && Object.keys(extra).length) { + event.extra = { ...extra, ...event.extra }; + } + if (tags && Object.keys(tags).length) { + event.tags = { ...tags, ...event.tags }; + } + if (user && Object.keys(user).length) { + event.user = { ...user, ...event.user }; + } + if (contexts && Object.keys(contexts).length) { + event.contexts = { ...contexts, ...event.contexts }; + } + if (level) { + event.level = level; + } + if (transactionName) { + event.transaction = transactionName; + } +} + +function applyBreadcrumbsToEvent(event: Event, breadcrumbs: Breadcrumb[]): void { + const mergedBreadcrumbs = [...(event.breadcrumbs || []), ...breadcrumbs]; + event.breadcrumbs = mergedBreadcrumbs.length ? mergedBreadcrumbs : undefined; +} + +function applySdkMetadataToEvent( + event: Event, + sdkProcessingMetadata: ScopeData['sdkProcessingMetadata'], + propagationContext: PropagationContext, +): void { + event.sdkProcessingMetadata = { + ...event.sdkProcessingMetadata, + ...sdkProcessingMetadata, + propagationContext: propagationContext, + }; +} + +function applySpanToEvent(event: Event, span: Span): void { + event.contexts = { trace: span.getTraceContext(), ...event.contexts }; + const transaction = span.transaction; + if (transaction) { + event.sdkProcessingMetadata = { + dynamicSamplingContext: transaction.getDynamicSamplingContext(), + ...event.sdkProcessingMetadata, + }; + const transactionName = transaction.name; + if (transactionName) { + event.tags = { transaction: transactionName, ...event.tags }; + } + } +} + +/** + * Applies fingerprint from the scope to the event if there's one, + * uses message if there's one instead or get rid of empty fingerprint + */ +function applyFingerprintToEvent(event: Event, fingerprint: ScopeData['fingerprint'] | undefined): void { + // Make sure it's an array first and we actually have something in place + event.fingerprint = event.fingerprint ? arrayify(event.fingerprint) : []; + + // If we have something on the scope, then merge it with event + if (fingerprint) { + event.fingerprint = event.fingerprint.concat(fingerprint); + } + + // If we have no data at all, remove empty array default + if (event.fingerprint && !event.fingerprint.length) { + delete event.fingerprint; + } +} diff --git a/packages/core/src/utils/prepareEvent.ts b/packages/core/src/utils/prepareEvent.ts index 46b26070653f..76307b4f45e6 100644 --- a/packages/core/src/utils/prepareEvent.ts +++ b/packages/core/src/utils/prepareEvent.ts @@ -9,19 +9,12 @@ import type { StackFrame, StackParser, } from '@sentry/types'; -import { - GLOBAL_OBJ, - addExceptionMechanism, - dateTimestampInSeconds, - normalize, - resolvedSyncPromise, - truncate, - uuid4, -} from '@sentry/utils'; +import { GLOBAL_OBJ, addExceptionMechanism, dateTimestampInSeconds, normalize, truncate, uuid4 } from '@sentry/utils'; import { DEFAULT_ENVIRONMENT } from '../constants'; import { getGlobalEventProcessors, notifyEventProcessors } from '../eventProcessors'; import { Scope } from '../scope'; +import { applyScopeDataToEvent } from './applyScopeDataToEvent'; /** * This type makes sure that we get either a CaptureContext, OR an EventHint. @@ -80,10 +73,13 @@ export function prepareEvent( addExceptionMechanism(prepared, hint.mechanism); } - // We prepare the result here with a resolved Event. - let result = resolvedSyncPromise(prepared); - const clientEventProcessors = client && client.getEventProcessors ? client.getEventProcessors() : []; + // TODO (v8): Update this order to be: Global > Client > Scope + const eventProcessors = [ + ...clientEventProcessors, + // eslint-disable-next-line deprecation/deprecation + ...getGlobalEventProcessors(), + ]; // This should be the last thing called, since we want that // {@link Hub.addEventProcessor} gets the finished prepared event. @@ -102,22 +98,15 @@ export function prepareEvent( } } - // In case we have a hub we reassign it. - result = finalScope.applyToEvent(prepared, hint, clientEventProcessors); - } else { - // Apply client & global event processors even if there is no scope - // TODO (v8): Update the order to be Global > Client - result = notifyEventProcessors( - [ - ...clientEventProcessors, - // eslint-disable-next-line deprecation/deprecation - ...getGlobalEventProcessors(), - ], - prepared, - hint, - ); + const scopeData = finalScope.getScopeData(); + applyScopeDataToEvent(prepared, scopeData); + + // Run scope event processors _after_ all other processors + eventProcessors.push(...scopeData.eventProcessors); } + const result = notifyEventProcessors(eventProcessors, prepared, hint); + return result.then(evt => { if (evt) { // We apply the debug_meta field only after all event processors have ran, so that if any event processors modified diff --git a/packages/feedback/test/unit/util/prepareFeedbackEvent.test.ts b/packages/feedback/test/unit/util/prepareFeedbackEvent.test.ts index 0958b164e34d..46311f1f0374 100644 --- a/packages/feedback/test/unit/util/prepareFeedbackEvent.test.ts +++ b/packages/feedback/test/unit/util/prepareFeedbackEvent.test.ts @@ -16,7 +16,7 @@ describe('Unit | util | prepareFeedbackEvent', () => { hub.bindClient(client); client = hub.getClient()!; - scope = hub.getScope()!; + scope = hub.getScope(); }); afterEach(() => { diff --git a/packages/node-experimental/src/sdk/scope.ts b/packages/node-experimental/src/sdk/scope.ts index f3195c7141b6..5bf220708a6a 100644 --- a/packages/node-experimental/src/sdk/scope.ts +++ b/packages/node-experimental/src/sdk/scope.ts @@ -1,15 +1,5 @@ -import { notifyEventProcessors } from '@sentry/core'; import { OpenTelemetryScope } from '@sentry/opentelemetry'; -import type { - Attachment, - Breadcrumb, - Client, - Event, - EventHint, - EventProcessor, - Severity, - SeverityLevel, -} from '@sentry/types'; +import type { Attachment, Breadcrumb, Client, Event, EventHint, Severity, SeverityLevel } from '@sentry/types'; import { uuid4 } from '@sentry/utils'; import { getGlobalCarrier } from './globals'; @@ -116,13 +106,7 @@ export class Scope extends OpenTelemetryScope implements ScopeInterface { /** @inheritdoc */ public getAttachments(): Attachment[] { - const data = getGlobalScope().getScopeData(); - const isolationScopeData = this._getIsolationScope().getScopeData(); - const scopeData = this.getScopeData(); - - // Merge data together, in order - mergeData(data, isolationScopeData); - mergeData(data, scopeData); + const data = this.getScopeData(); return data.attachments; } @@ -200,7 +184,7 @@ export class Scope extends OpenTelemetryScope implements ScopeInterface { } /** Get all relevant data for this scope. */ - public getScopeData(): ScopeData { + public getPerScopeData(): ScopeData { const { _breadcrumbs, _attachments, @@ -230,63 +214,17 @@ export class Scope extends OpenTelemetryScope implements ScopeInterface { }; } - /** - * Applies data from the scope to the event and runs all event processors on it. - * - * @param event Event - * @param hint Object containing additional information about the original exception, for use by the event processors. - * @hidden - */ - public applyToEvent( - event: Event, - hint: EventHint = {}, - additionalEventProcessors: EventProcessor[] = [], - ): PromiseLike { - const data = getGlobalScope().getScopeData(); - const isolationScopeData = this._getIsolationScope().getScopeData(); - const scopeData = this.getScopeData(); + /** @inheritdoc */ + public getScopeData(): ScopeData { + const data = getGlobalScope().getPerScopeData(); + const isolationScopeData = this._getIsolationScope().getPerScopeData(); + const scopeData = this.getPerScopeData(); // Merge data together, in order mergeData(data, isolationScopeData); mergeData(data, scopeData); - // Apply the data - const { extra, tags, user, contexts, level, sdkProcessingMetadata, breadcrumbs, fingerprint, eventProcessors } = - data; - - mergePropKeep(event, 'extra', extra); - mergePropKeep(event, 'tags', tags); - mergePropKeep(event, 'user', user); - mergePropKeep(event, 'contexts', contexts); - mergePropKeep(event, 'sdkProcessingMetadata', sdkProcessingMetadata); - event.sdkProcessingMetadata = { - ...event.sdkProcessingMetadata, - propagationContext: this._propagationContext, - }; - - mergeArray(event, 'breadcrumbs', breadcrumbs); - mergeArray(event, 'fingerprint', fingerprint); - - if (level) { - event.level = level; - } - - const allEventProcessors = [...additionalEventProcessors, ...eventProcessors]; - - // Apply additional things to the event - if (this._transactionName) { - event.transaction = this._transactionName; - } - - return notifyEventProcessors(allEventProcessors, event, hint); - } - - /** - * Get all breadcrumbs attached to this scope. - * @internal - */ - public getBreadcrumbs(): Breadcrumb[] { - return this._breadcrumbs; + return data; } /** Get the isolation scope for this scope. */ @@ -308,6 +246,7 @@ export function mergeData(data: ScopeData, mergeData: ScopeData): void { fingerprint, eventProcessors, attachments, + propagationContext, } = mergeData; mergePropOverwrite(data, 'extra', extra); @@ -335,6 +274,8 @@ export function mergeData(data: ScopeData, mergeData: ScopeData): void { if (attachments.length) { data.attachments = [...data.attachments, ...attachments]; } + + data.propagationContext = { ...data.propagationContext, ...propagationContext }; } /** diff --git a/packages/node-experimental/test/sdk/scope.test.ts b/packages/node-experimental/test/sdk/scope.test.ts index a0e179373626..9fb5c02bea69 100644 --- a/packages/node-experimental/test/sdk/scope.test.ts +++ b/packages/node-experimental/test/sdk/scope.test.ts @@ -1,3 +1,4 @@ +import { applyScopeDataToEvent } from '@sentry/core'; import type { Attachment, Breadcrumb, Client, EventProcessor } from '@sentry/types'; import { Scope, getIsolationScope } from '../../src'; import { getGlobalScope, mergeArray, mergeData, mergePropKeep, mergePropOverwrite } from '../../src/sdk/scope'; @@ -295,8 +296,7 @@ describe('Unit | Scope', () => { extra: { extra1: 'aa', extra2: 'bb', extra3: 'bb' }, contexts: { os: { name: 'os2' }, culture: { display_name: 'name1' } }, attachments: [attachment1, attachment2, attachment3], - // This is not merged, we always use the one from the scope here anyhow - propagationContext: { spanId: '1', traceId: '1' }, + propagationContext: { spanId: '2', traceId: '2' }, sdkProcessingMetadata: { aa: 'aa', bb: 'bb', cc: 'bb' }, fingerprint: ['aa', 'bb', 'cc'], }); @@ -309,7 +309,8 @@ describe('Unit | Scope', () => { const scope = new Scope(); - const event = await scope.applyToEvent({ message: 'foo' }); + const event = { message: 'foo' }; + applyScopeDataToEvent(event, scope.getScopeData()); expect(event).toEqual({ message: 'foo', @@ -357,11 +358,9 @@ describe('Unit | Scope', () => { isolationScope.addEventProcessor(eventProcessor3); globalScope.setSDKProcessingMetadata({ bb: 'bb' }); - const event = await scope.applyToEvent({ - message: 'foo', - breadcrumbs: [breadcrumb4], - fingerprint: ['dd'], - }); + const event = { message: 'foo', breadcrumbs: [breadcrumb4], fingerprint: ['dd'] }; + + applyScopeDataToEvent(event, scope.getScopeData()); expect(event).toEqual({ message: 'foo', diff --git a/packages/node/src/integrations/hapi/index.ts b/packages/node/src/integrations/hapi/index.ts index 42e7d27bca9e..5e158af810ca 100644 --- a/packages/node/src/integrations/hapi/index.ts +++ b/packages/node/src/integrations/hapi/index.ts @@ -38,6 +38,7 @@ function sendErrorToSentry(errorData: object): void { export const hapiErrorPlugin = { name: 'SentryHapiErrorPlugin', version: SDK_VERSION, + // eslint-disable-next-line @typescript-eslint/no-explicit-any register: async function (serverArg: Record) { const server = serverArg as unknown as Server; @@ -61,6 +62,7 @@ export const hapiErrorPlugin = { export const hapiTracingPlugin = { name: 'SentryHapiTracingPlugin', version: SDK_VERSION, + // eslint-disable-next-line @typescript-eslint/no-explicit-any register: async function (serverArg: Record) { const server = serverArg as unknown as Server; @@ -122,6 +124,7 @@ export const hapiTracingPlugin = { export type HapiOptions = { /** Hapi server instance */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any server?: Record; }; diff --git a/packages/node/test/integrations/requestdata.test.ts b/packages/node/test/integrations/requestdata.test.ts index 7b5dc41434db..61f71873fff4 100644 --- a/packages/node/test/integrations/requestdata.test.ts +++ b/packages/node/test/integrations/requestdata.test.ts @@ -1,5 +1,7 @@ import * as http from 'http'; import type { RequestDataIntegrationOptions } from '@sentry/core'; +import { applyScopeDataToEvent } from '@sentry/core'; +import { getCurrentScope } from '@sentry/core'; import { RequestData, getCurrentHub } from '@sentry/core'; import type { Event, EventProcessor, PolymorphicRequest } from '@sentry/types'; import * as sentryUtils from '@sentry/utils'; @@ -67,7 +69,7 @@ describe('`RequestData` integration', () => { sentryRequestMiddleware(req, res, next); - await getCurrentHub().getScope()!.applyToEvent(event, {}); + applyScopeDataToEvent(event, getCurrentScope().getScopeData()); void requestDataEventProcessor(event, {}); const passedOptions = addRequestDataToEventSpy.mock.calls[0][2]; @@ -80,7 +82,7 @@ describe('`RequestData` integration', () => { type GCPHandler = (req: PolymorphicRequest, res: http.ServerResponse) => void; const mockGCPWrapper = (origHandler: GCPHandler, options: Record): GCPHandler => { const wrappedHandler: GCPHandler = (req, res) => { - getCurrentHub().getScope().setSDKProcessingMetadata({ + getCurrentScope().setSDKProcessingMetadata({ request: req, requestDataOptionsFromGCPWrapper: options, }); @@ -96,7 +98,7 @@ describe('`RequestData` integration', () => { wrappedGCPFunction(req, res); - await getCurrentHub().getScope()!.applyToEvent(event, {}); + applyScopeDataToEvent(event, getCurrentScope().getScopeData()); void requestDataEventProcessor(event, {}); const passedOptions = addRequestDataToEventSpy.mock.calls[0][2]; diff --git a/packages/opentelemetry/src/custom/scope.ts b/packages/opentelemetry/src/custom/scope.ts index e08f8484d87d..c6bdfb164900 100644 --- a/packages/opentelemetry/src/custom/scope.ts +++ b/packages/opentelemetry/src/custom/scope.ts @@ -1,7 +1,7 @@ import type { Span } from '@opentelemetry/api'; import type { TimedEvent } from '@opentelemetry/sdk-trace-base'; import { Scope } from '@sentry/core'; -import type { Breadcrumb, SeverityLevel, Span as SentrySpan } from '@sentry/types'; +import type { Breadcrumb, ScopeData, SeverityLevel, Span as SentrySpan } from '@sentry/types'; import { dateTimestampInSeconds, dropUndefinedKeys, logger, normalize } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; @@ -90,6 +90,15 @@ export class OpenTelemetryScope extends Scope { return this._addBreadcrumb(breadcrumb, maxBreadcrumbs); } + /** @inheritDoc */ + public getScopeData(): ScopeData { + const data = super.getScopeData(); + + data.breadcrumbs = this._getBreadcrumbs(); + + return data; + } + /** Add a breadcrumb to this scope. */ protected _addBreadcrumb(breadcrumb: Breadcrumb, maxBreadcrumbs?: number): this { return super.addBreadcrumb(breadcrumb, maxBreadcrumbs); diff --git a/packages/replay/test/unit/util/prepareReplayEvent.test.ts b/packages/replay/test/unit/util/prepareReplayEvent.test.ts index 33019507046a..867bb801907a 100644 --- a/packages/replay/test/unit/util/prepareReplayEvent.test.ts +++ b/packages/replay/test/unit/util/prepareReplayEvent.test.ts @@ -17,7 +17,7 @@ describe('Unit | util | prepareReplayEvent', () => { hub.bindClient(client); client = hub.getClient()!; - scope = hub.getScope()!; + scope = hub.getScope(); jest.spyOn(client, 'getSdkMetadata').mockImplementation(() => { return { diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index a2d75a193414..34e4cd40a741 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -72,7 +72,7 @@ export type { ReplayEvent, ReplayRecordingData, ReplayRecordingMode } from './re export type { FeedbackEvent } from './feedback'; export type { QueryParams, Request, SanitizedRequestData } from './request'; export type { Runtime } from './runtime'; -export type { CaptureContext, Scope, ScopeContext } from './scope'; +export type { CaptureContext, Scope, ScopeContext, ScopeData } from './scope'; export type { SdkInfo } from './sdkinfo'; export type { SdkMetadata } from './sdkmetadata'; export type { diff --git a/packages/types/src/scope.ts b/packages/types/src/scope.ts index 4a315aa7adda..50ef4da5987f 100644 --- a/packages/types/src/scope.ts +++ b/packages/types/src/scope.ts @@ -27,6 +27,22 @@ export interface ScopeContext { propagationContext: PropagationContext; } +export interface ScopeData { + eventProcessors: EventProcessor[]; + breadcrumbs: Breadcrumb[]; + user: User; + tags: { [key: string]: Primitive }; + extra: Extras; + contexts: Contexts; + attachments: Attachment[]; + propagationContext: PropagationContext; + sdkProcessingMetadata: { [key: string]: unknown }; + fingerprint: string[]; + level?: SeverityLevel; + transactionName?: string; + span?: Span; +} + /** * Holds additional event information. {@link Scope.applyToEvent} will be called by the client before an event is sent. */ @@ -34,6 +50,9 @@ export interface Scope { /** Add new event processor that will be called after {@link applyToEvent}. */ addEventProcessor(callback: EventProcessor): this; + /** Get the data of this scope, which is applied to an event during processing. */ + getScopeData(): ScopeData; + /** * Updates user context information for future events. *