@@ -23,26 +23,23 @@ import {
2323 addItemToEnvelope ,
2424 checkOrSetAlreadyCaught ,
2525 createAttachmentEnvelopeItem ,
26- dateTimestampInSeconds ,
2726 isPlainObject ,
2827 isPrimitive ,
2928 isThenable ,
3029 logger ,
3130 makeDsn ,
32- normalize ,
3331 rejectedSyncPromise ,
3432 resolvedSyncPromise ,
3533 SentryError ,
3634 SyncPromise ,
37- truncate ,
38- uuid4 ,
3935} from '@sentry/utils' ;
4036
4137import { getEnvelopeEndpointWithUrlEncodedAuth } from './api' ;
4238import { createEventEnvelope , createSessionEnvelope } from './envelope' ;
4339import { IntegrationIndex , setupIntegrations } from './integration' ;
4440import { Scope } from './scope' ;
4541import { updateSession } from './session' ;
42+ import { prepareEvent } from './utils/prepareEvent' ;
4643
4744const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured." ;
4845
@@ -322,7 +319,7 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
322319 // Note: we use `event` in replay, where we overwrite this hook.
323320
324321 if ( this . _options . sendClientReports ) {
325- // We want to track each category (error, transaction, session) separately
322+ // We want to track each category (error, transaction, session, replay_event ) separately
326323 // but still keep the distinction between different type of outcomes.
327324 // We could use nested maps, but it's much easier to read and type this way.
328325 // A correct type for map-based implementation if we want to go that route
@@ -419,166 +416,8 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
419416 * @returns A new event with more information.
420417 */
421418 protected _prepareEvent ( event : Event , hint : EventHint , scope ?: Scope ) : PromiseLike < Event | null > {
422- const { normalizeDepth = 3 , normalizeMaxBreadth = 1_000 } = this . getOptions ( ) ;
423- const prepared : Event = {
424- ...event ,
425- event_id : event . event_id || hint . event_id || uuid4 ( ) ,
426- timestamp : event . timestamp || dateTimestampInSeconds ( ) ,
427- } ;
428-
429- this . _applyClientOptions ( prepared ) ;
430- this . _applyIntegrationsMetadata ( prepared ) ;
431-
432- // If we have scope given to us, use it as the base for further modifications.
433- // This allows us to prevent unnecessary copying of data if `captureContext` is not provided.
434- let finalScope = scope ;
435- if ( hint . captureContext ) {
436- finalScope = Scope . clone ( finalScope ) . update ( hint . captureContext ) ;
437- }
438-
439- // We prepare the result here with a resolved Event.
440- let result = resolvedSyncPromise < Event | null > ( prepared ) ;
441-
442- // This should be the last thing called, since we want that
443- // {@link Hub.addEventProcessor } gets the finished prepared event.
444- //
445- // We need to check for the existence of `finalScope.getAttachments`
446- // because `getAttachments` can be undefined if users are using an older version
447- // of `@sentry/core` that does not have the `getAttachments` method.
448- // See: https://github.com/getsentry/sentry-javascript/issues/5229
449- if ( finalScope && finalScope . getAttachments ) {
450- // Collect attachments from the hint and scope
451- const attachments = [ ...( hint . attachments || [ ] ) , ...finalScope . getAttachments ( ) ] ;
452-
453- if ( attachments . length ) {
454- hint . attachments = attachments ;
455- }
456-
457- // In case we have a hub we reassign it.
458- result = finalScope . applyToEvent ( prepared , hint ) ;
459- }
460-
461- return result . then ( evt => {
462- if ( typeof normalizeDepth === 'number' && normalizeDepth > 0 ) {
463- return this . _normalizeEvent ( evt , normalizeDepth , normalizeMaxBreadth ) ;
464- }
465- return evt ;
466- } ) ;
467- }
468-
469- /**
470- * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization.
471- * Normalized keys:
472- * - `breadcrumbs.data`
473- * - `user`
474- * - `contexts`
475- * - `extra`
476- * @param event Event
477- * @returns Normalized event
478- */
479- protected _normalizeEvent ( event : Event | null , depth : number , maxBreadth : number ) : Event | null {
480- if ( ! event ) {
481- return null ;
482- }
483-
484- const normalized : Event = {
485- ...event ,
486- ...( event . breadcrumbs && {
487- breadcrumbs : event . breadcrumbs . map ( b => ( {
488- ...b ,
489- ...( b . data && {
490- data : normalize ( b . data , depth , maxBreadth ) ,
491- } ) ,
492- } ) ) ,
493- } ) ,
494- ...( event . user && {
495- user : normalize ( event . user , depth , maxBreadth ) ,
496- } ) ,
497- ...( event . contexts && {
498- contexts : normalize ( event . contexts , depth , maxBreadth ) ,
499- } ) ,
500- ...( event . extra && {
501- extra : normalize ( event . extra , depth , maxBreadth ) ,
502- } ) ,
503- } ;
504-
505- // event.contexts.trace stores information about a Transaction. Similarly,
506- // event.spans[] stores information about child Spans. Given that a
507- // Transaction is conceptually a Span, normalization should apply to both
508- // Transactions and Spans consistently.
509- // For now the decision is to skip normalization of Transactions and Spans,
510- // so this block overwrites the normalized event to add back the original
511- // Transaction information prior to normalization.
512- if ( event . contexts && event . contexts . trace && normalized . contexts ) {
513- normalized . contexts . trace = event . contexts . trace ;
514-
515- // event.contexts.trace.data may contain circular/dangerous data so we need to normalize it
516- if ( event . contexts . trace . data ) {
517- normalized . contexts . trace . data = normalize ( event . contexts . trace . data , depth , maxBreadth ) ;
518- }
519- }
520-
521- // event.spans[].data may contain circular/dangerous data so we need to normalize it
522- if ( event . spans ) {
523- normalized . spans = event . spans . map ( span => {
524- // We cannot use the spread operator here because `toJSON` on `span` is non-enumerable
525- if ( span . data ) {
526- span . data = normalize ( span . data , depth , maxBreadth ) ;
527- }
528- return span ;
529- } ) ;
530- }
531-
532- return normalized ;
533- }
534-
535- /**
536- * Enhances event using the client configuration.
537- * It takes care of all "static" values like environment, release and `dist`,
538- * as well as truncating overly long values.
539- * @param event event instance to be enhanced
540- */
541- protected _applyClientOptions ( event : Event ) : void {
542419 const options = this . getOptions ( ) ;
543- const { environment, release, dist, maxValueLength = 250 } = options ;
544-
545- if ( ! ( 'environment' in event ) ) {
546- event . environment = 'environment' in options ? environment : 'production' ;
547- }
548-
549- if ( event . release === undefined && release !== undefined ) {
550- event . release = release ;
551- }
552-
553- if ( event . dist === undefined && dist !== undefined ) {
554- event . dist = dist ;
555- }
556-
557- if ( event . message ) {
558- event . message = truncate ( event . message , maxValueLength ) ;
559- }
560-
561- const exception = event . exception && event . exception . values && event . exception . values [ 0 ] ;
562- if ( exception && exception . value ) {
563- exception . value = truncate ( exception . value , maxValueLength ) ;
564- }
565-
566- const request = event . request ;
567- if ( request && request . url ) {
568- request . url = truncate ( request . url , maxValueLength ) ;
569- }
570- }
571-
572- /**
573- * This function adds all used integrations to the SDK info in the event.
574- * @param event The event that will be filled with all integrations.
575- */
576- protected _applyIntegrationsMetadata ( event : Event ) : void {
577- const integrationsArray = Object . keys ( this . _integrations ) ;
578- if ( integrationsArray . length > 0 ) {
579- event . sdk = event . sdk || { } ;
580- event . sdk . integrations = [ ...( event . sdk . integrations || [ ] ) , ...integrationsArray ] ;
581- }
420+ return prepareEvent ( options , event , hint , scope ) ;
582421 }
583422
584423 /**
0 commit comments