_prepareEvent(
    event,
    hint,
    scope,
    isolationScope = hub.getIsolationScope(),
  ) {
    const options = this.getOptions();
    const integrations = Object.keys(this._integrations);
    if (!hint.integrations && integrations.length > 0) {
      hint.integrations = integrations;
    }

    this.emit('preprocessEvent', event, hint);

    return prepareEvent.prepareEvent(options, event, hint, scope, this, isolationScope).then(evt => {
      if (evt === null) {
        return evt;
      }

      const propagationContext = {
        ...isolationScope.getPropagationContext(),
        ...(scope ? scope.getPropagationContext() : undefined),
      };

      const trace = evt.contexts && evt.contexts.trace;
      if (!trace && propagationContext) {
        const { traceId: trace_id, spanId, parentSpanId, dsc } = propagationContext;
        evt.contexts = {
          trace: {
            trace_id,
            span_id: spanId,
            parent_span_id: parentSpanId,
          },
          ...evt.contexts,
        };

        const dynamicSamplingContext$1 = dsc ? dsc : dynamicSamplingContext.getDynamicSamplingContextFromClient(trace_id, this, scope);

        evt.sdkProcessingMetadata = {
          dynamicSamplingContext: dynamicSamplingContext$1,
          ...evt.sdkProcessingMetadata,
        };
      }
      return evt;
    });
  }
Adds common information to events.

The information includes release and environment from `options`,
breadcrumbs and context (extra, tags and user) from the scope.

Information that is already present in the event is never overwritten. For
nested objects, such as the context, keys are merged.

@param event The original event.
@param hint May contain additional information about the original exception.
@param scope A scope containing event metadata.
@returns A new event with more information.