Skip to content

Commit b1009b5

Browse files
authored
ref(core): Use helpers with event envelopes (#4656)
This patch converts the events logic in `packages/core/src/request.ts` to use the recently introduced envelope helpers. ref: #4587
1 parent e0ca11e commit b1009b5

File tree

3 files changed

+37
-35
lines changed

3 files changed

+37
-35
lines changed

packages/core/src/request.ts

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
import { Event, SdkInfo, SentryRequest, SentryRequestType, Session, SessionAggregates } from '@sentry/types';
2-
import { dsnToString, normalize } from '@sentry/utils';
1+
import {
2+
Event,
3+
EventEnvelope,
4+
EventItem,
5+
SdkInfo,
6+
SentryRequest,
7+
SentryRequestType,
8+
Session,
9+
SessionAggregates,
10+
} from '@sentry/types';
11+
import { createEnvelope, dsnToString, normalize, serializeEnvelope } from '@sentry/utils';
312

413
import { APIDetails, getEnvelopeEndpointWithUrlEncodedAuth, getStoreEndpointWithUrlEncodedAuth } from './api';
514

@@ -128,39 +137,21 @@ export function eventToSentryRequest(event: Event, api: APIDetails): SentryReque
128137
// deserialization. Instead, we only implement a minimal subset of the spec to
129138
// serialize events inline here.
130139
if (useEnvelope) {
131-
const envelopeHeaders = JSON.stringify({
132-
event_id: event.event_id,
140+
const envelopeHeaders = {
141+
event_id: event.event_id as string,
133142
sent_at: new Date().toISOString(),
134143
...(sdkInfo && { sdk: sdkInfo }),
135144
...(!!api.tunnel && { dsn: dsnToString(api.dsn) }),
136-
});
137-
const itemHeaders = JSON.stringify({
138-
type: eventType,
139-
140-
// TODO: Right now, sampleRate may or may not be defined (it won't be in the cases of inheritance and
141-
// explicitly-set sampling decisions). Are we good with that?
142-
sample_rates: [{ id: samplingMethod, rate: sampleRate }],
143-
144-
// The content-type is assumed to be 'application/json' and not part of
145-
// the current spec for transaction items, so we don't bloat the request
146-
// body with it.
147-
//
148-
// content_type: 'application/json',
149-
//
150-
// The length is optional. It must be the number of bytes in req.Body
151-
// encoded as UTF-8. Since the server can figure this out and would
152-
// otherwise refuse events that report the length incorrectly, we decided
153-
// not to send the length to avoid problems related to reporting the wrong
154-
// size and to reduce request body size.
155-
//
156-
// length: new TextEncoder().encode(req.body).length,
157-
});
158-
// The trailing newline is optional. We intentionally don't send it to avoid
159-
// sending unnecessary bytes.
160-
//
161-
// const envelope = `${envelopeHeaders}\n${itemHeaders}\n${req.body}\n`;
162-
const envelope = `${envelopeHeaders}\n${itemHeaders}\n${req.body}`;
163-
req.body = envelope;
145+
};
146+
const eventItem: EventItem = [
147+
{
148+
type: eventType,
149+
sample_rates: [{ id: samplingMethod, rate: sampleRate }],
150+
},
151+
req.body,
152+
];
153+
const envelope = createEnvelope<EventEnvelope>(envelopeHeaders, [eventItem]);
154+
req.body = serializeEnvelope(envelope);
164155
}
165156

166157
return req;

packages/types/src/envelope.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ClientReport } from './clientreport';
22
import { Event } from './event';
33
import { SdkInfo } from './sdkinfo';
44
import { Session, SessionAggregates } from './session';
5+
import { TransactionSamplingMethod } from './transaction';
56
import { UserFeedback } from './user';
67

78
// Based on: https://develop.sentry.dev/sdk/envelopes/
@@ -25,14 +26,20 @@ type BaseEnvelope<EH extends BaseEnvelopeHeaders, I extends BaseEnvelopeItem<Bas
2526
I[],
2627
];
2728

28-
type EventItemHeaders = { type: 'event' | 'transaction' };
29+
type EventItemHeaders = {
30+
type: 'event' | 'transaction';
31+
sample_rates: [{ id?: TransactionSamplingMethod; rate?: number }];
32+
};
2933
type AttachmentItemHeaders = { type: 'attachment'; filename: string };
3034
type UserFeedbackItemHeaders = { type: 'user_report' };
3135
type SessionItemHeaders = { type: 'session' };
3236
type SessionAggregatesItemHeaders = { type: 'sessions' };
3337
type ClientReportItemHeaders = { type: 'client_report' };
3438

35-
export type EventItem = BaseEnvelopeItem<EventItemHeaders, Event>;
39+
// TODO(v7): Remove the string union from `Event | string`
40+
// We have to allow this hack for now as we pre-serialize events because we support
41+
// both store and envelope endpoints.
42+
export type EventItem = BaseEnvelopeItem<EventItemHeaders, Event | string>;
3643
export type AttachmentItem = BaseEnvelopeItem<AttachmentItemHeaders, unknown>;
3744
export type UserFeedbackItem = BaseEnvelopeItem<UserFeedbackItemHeaders, UserFeedback>;
3845
export type SessionItem =

packages/utils/src/envelope.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Envelope } from '@sentry/types';
22

3+
import { isPrimitive } from './is';
4+
35
/**
46
* Creates an envelope.
57
* Make sure to always explicitly provide the generic to this function
@@ -33,6 +35,8 @@ export function serializeEnvelope(envelope: Envelope): string {
3335
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3436
return (items as any[]).reduce((acc, item: typeof items[number]) => {
3537
const [itemHeaders, payload] = item;
36-
return `${acc}\n${JSON.stringify(itemHeaders)}\n${JSON.stringify(payload)}`;
38+
// We do not serialize payloads that are primitives
39+
const serializedPayload = isPrimitive(payload) ? String(payload) : JSON.stringify(payload);
40+
return `${acc}\n${JSON.stringify(itemHeaders)}\n${serializedPayload}`;
3741
}, serializedHeaders);
3842
}

0 commit comments

Comments
 (0)