From 2c4cfa9186882cfa02f723931acf70d0e71224c8 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 1 Mar 2022 10:56:15 -0500 Subject: [PATCH 1/4] ref(core): Use helpers with event envelopes This patch converts the events logic in `packages/core/src/request.ts` to use the recently introduced envelope helpers. ref: https://github.com/getsentry/sentry-javascript/pull/4587 --- packages/core/src/request.ts | 55 ++++++++++++++-------------------- packages/types/src/envelope.ts | 7 +++-- packages/utils/src/envelope.ts | 4 ++- 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/packages/core/src/request.ts b/packages/core/src/request.ts index e5050c04d070..36952e66d461 100644 --- a/packages/core/src/request.ts +++ b/packages/core/src/request.ts @@ -1,5 +1,14 @@ -import { Event, SdkInfo, SentryRequest, SentryRequestType, Session, SessionAggregates } from '@sentry/types'; -import { dsnToString, normalize } from '@sentry/utils'; +import { + Event, + EventEnvelope, + EventItem, + SdkInfo, + SentryRequest, + SentryRequestType, + Session, + SessionAggregates, +} from '@sentry/types'; +import { createEnvelope, dsnToString, normalize, serializeEnvelope } from '@sentry/utils'; import { APIDetails, getEnvelopeEndpointWithUrlEncodedAuth, getStoreEndpointWithUrlEncodedAuth } from './api'; @@ -128,39 +137,21 @@ export function eventToSentryRequest(event: Event, api: APIDetails): SentryReque // deserialization. Instead, we only implement a minimal subset of the spec to // serialize events inline here. if (useEnvelope) { - const envelopeHeaders = JSON.stringify({ - event_id: event.event_id, + const envelopeHeaders = { + event_id: event.event_id as string, sent_at: new Date().toISOString(), ...(sdkInfo && { sdk: sdkInfo }), ...(!!api.tunnel && { dsn: dsnToString(api.dsn) }), - }); - const itemHeaders = JSON.stringify({ - type: eventType, - - // TODO: Right now, sampleRate may or may not be defined (it won't be in the cases of inheritance and - // explicitly-set sampling decisions). Are we good with that? - sample_rates: [{ id: samplingMethod, rate: sampleRate }], - - // The content-type is assumed to be 'application/json' and not part of - // the current spec for transaction items, so we don't bloat the request - // body with it. - // - // content_type: 'application/json', - // - // The length is optional. It must be the number of bytes in req.Body - // encoded as UTF-8. Since the server can figure this out and would - // otherwise refuse events that report the length incorrectly, we decided - // not to send the length to avoid problems related to reporting the wrong - // size and to reduce request body size. - // - // length: new TextEncoder().encode(req.body).length, - }); - // The trailing newline is optional. We intentionally don't send it to avoid - // sending unnecessary bytes. - // - // const envelope = `${envelopeHeaders}\n${itemHeaders}\n${req.body}\n`; - const envelope = `${envelopeHeaders}\n${itemHeaders}\n${req.body}`; - req.body = envelope; + }; + const eventItem: EventItem = [ + { + type: eventType, + sample_rates: [{ id: samplingMethod, rate: sampleRate }], + }, + req.body, + ]; + const envelope = createEnvelope(envelopeHeaders, [eventItem]); + req.body = serializeEnvelope(envelope); } return req; diff --git a/packages/types/src/envelope.ts b/packages/types/src/envelope.ts index aa7655db9cea..5e3f07b6b1e2 100644 --- a/packages/types/src/envelope.ts +++ b/packages/types/src/envelope.ts @@ -25,14 +25,17 @@ type BaseEnvelope; +// TODO(v7): Remove the string union from `Event | string` +// We have to allow this hack for now as we pre-serialize events because we support +// both store and envelope endpoints. +export type EventItem = BaseEnvelopeItem; export type AttachmentItem = BaseEnvelopeItem; export type UserFeedbackItem = BaseEnvelopeItem; export type SessionItem = diff --git a/packages/utils/src/envelope.ts b/packages/utils/src/envelope.ts index 7552bd339784..68d8f91cb67a 100644 --- a/packages/utils/src/envelope.ts +++ b/packages/utils/src/envelope.ts @@ -33,6 +33,8 @@ export function serializeEnvelope(envelope: Envelope): string { // eslint-disable-next-line @typescript-eslint/no-explicit-any return (items as any[]).reduce((acc, item: typeof items[number]) => { const [itemHeaders, payload] = item; - return `${acc}\n${JSON.stringify(itemHeaders)}\n${JSON.stringify(payload)}`; + // We do not serialize payloads that are strings + const serializedPayload = typeof payload === 'string' ? payload : JSON.stringify(payload); + return `${acc}\n${JSON.stringify(itemHeaders)}\n${serializedPayload}`; }, serializedHeaders); } From 9051a9fe1bca796cbb9593aba5ed1f5845fc5804 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 1 Mar 2022 12:04:01 -0500 Subject: [PATCH 2/4] isPrimitive check --- packages/utils/src/envelope.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/envelope.ts b/packages/utils/src/envelope.ts index 68d8f91cb67a..70294de1b21c 100644 --- a/packages/utils/src/envelope.ts +++ b/packages/utils/src/envelope.ts @@ -1,5 +1,7 @@ import { Envelope } from '@sentry/types'; +import { isPrimitive } from './is'; + /** * Creates an envelope. * Make sure to always explicitly provide the generic to this function @@ -33,8 +35,8 @@ export function serializeEnvelope(envelope: Envelope): string { // eslint-disable-next-line @typescript-eslint/no-explicit-any return (items as any[]).reduce((acc, item: typeof items[number]) => { const [itemHeaders, payload] = item; - // We do not serialize payloads that are strings - const serializedPayload = typeof payload === 'string' ? payload : JSON.stringify(payload); + // We do not serialize payloads that are primitives + const serializedPayload = isPrimitive(payload) ? String(payload) : JSON.stringify(payload); return `${acc}\n${JSON.stringify(itemHeaders)}\n${serializedPayload}`; }, serializedHeaders); } From c726b207a5b1a2178d923e51efb396c57d2428e3 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 1 Mar 2022 13:37:33 -0500 Subject: [PATCH 3/4] update sample_rates types --- packages/types/src/envelope.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/types/src/envelope.ts b/packages/types/src/envelope.ts index 5e3f07b6b1e2..84fe88ec9db9 100644 --- a/packages/types/src/envelope.ts +++ b/packages/types/src/envelope.ts @@ -3,6 +3,7 @@ import { Event } from './event'; import { SdkInfo } from './sdkinfo'; import { Session, SessionAggregates } from './session'; import { UserFeedback } from './user'; +import { TransactionSamplingMethod } from './transaction'; // Based on: https://develop.sentry.dev/sdk/envelopes/ @@ -25,7 +26,10 @@ type BaseEnvelope Date: Tue, 1 Mar 2022 14:13:36 -0500 Subject: [PATCH 4/4] yarn fix --- packages/types/src/envelope.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/envelope.ts b/packages/types/src/envelope.ts index 84fe88ec9db9..b03d42eb3ea8 100644 --- a/packages/types/src/envelope.ts +++ b/packages/types/src/envelope.ts @@ -2,8 +2,8 @@ import { ClientReport } from './clientreport'; import { Event } from './event'; import { SdkInfo } from './sdkinfo'; import { Session, SessionAggregates } from './session'; -import { UserFeedback } from './user'; import { TransactionSamplingMethod } from './transaction'; +import { UserFeedback } from './user'; // Based on: https://develop.sentry.dev/sdk/envelopes/