Skip to content

Commit 743ab6d

Browse files
committed
attachments in single envelope
1 parent 7f1b46d commit 743ab6d

File tree

10 files changed

+63
-133
lines changed

10 files changed

+63
-133
lines changed

dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect } from '@playwright/test';
2-
import type { SpanEnvelope, Event } from '@sentry/types';
2+
import type { Event, SpanEnvelope } from '@sentry/types';
33
import { sentryTest } from '../../../../utils/fixtures';
44
import type { EventAndTraceHeader } from '../../../../utils/helpers';
55
import {

dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect } from '@playwright/test';
2-
import type { SpanEnvelope, Event } from '@sentry/types';
2+
import type { Event, SpanEnvelope } from '@sentry/types';
33
import { sentryTest } from '../../../../utils/fixtures';
44
import type { EventAndTraceHeader } from '../../../../utils/helpers';
55
import {

packages/core/src/envelope.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import type {
2-
Attachment,
3-
AttachmentItem,
42
DsnComponents,
53
DynamicSamplingContext,
64
Event,
@@ -15,7 +13,6 @@ import type {
1513
SpanEnvelope,
1614
} from '@sentry/types';
1715
import {
18-
createAttachmentEnvelopeItem,
1916
createEnvelope,
2017
createEventEnvelopeHeaders,
2118
dsnToString,
@@ -95,34 +92,6 @@ export function createEventEnvelope(
9592
return createEnvelope<EventEnvelope>(envelopeHeaders, [eventItem]);
9693
}
9794

98-
/**
99-
* Create an Envelope from an event.
100-
*/
101-
export function createAttachmentEnvelope(
102-
event: Event,
103-
attachments: Attachment[],
104-
dsn?: DsnComponents,
105-
metadata?: SdkMetadata,
106-
tunnel?: string,
107-
): EventEnvelope {
108-
const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);
109-
enhanceEventWithSdkInfo(event, metadata && metadata.sdk);
110-
111-
const envelopeHeaders = createEventEnvelopeHeaders(event, sdkInfo, tunnel, dsn);
112-
113-
// Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to
114-
// sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may
115-
// have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid
116-
// of this `delete`, lest we miss putting it back in the next time the property is in use.)
117-
delete event.sdkProcessingMetadata;
118-
119-
const attachmentItems: AttachmentItem[] = [];
120-
for (const attachment of attachments || []) {
121-
attachmentItems.push(createAttachmentEnvelopeItem(attachment));
122-
}
123-
return createEnvelope<EventEnvelope>(envelopeHeaders, attachmentItems);
124-
}
125-
12695
/**
12796
* Create envelope from Span item.
12897
*/

packages/core/src/feedback.ts

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
import type { EventHint, FeedbackEvent, SendFeedbackParams } from '@sentry/types';
22
import { dropUndefinedKeys } from '@sentry/utils';
33
import { getClient, getCurrentScope } from './currentScopes';
4-
import { createAttachmentEnvelope } from './envelope';
54

65
/**
76
* Send user feedback to Sentry.
87
*/
98
export function captureFeedback(
109
feedbackParams: SendFeedbackParams,
11-
hint?: EventHint & { includeReplay?: boolean },
10+
hint: EventHint & { includeReplay?: boolean } = {},
1211
): string {
13-
const { message, name, email, url, source, attachments, associatedEventId } = feedbackParams;
12+
const { message, name, email, url, source, associatedEventId } = feedbackParams;
1413

1514
const client = getClient();
16-
const transport = client && client.getTransport();
17-
const dsn = client && client.getDsn();
1815

1916
const feedbackEvent: FeedbackEvent = {
2017
contexts: {
@@ -37,25 +34,5 @@ export function captureFeedback(
3734

3835
const eventId = getCurrentScope().captureEvent(feedbackEvent, hint);
3936

40-
// For now, we have to send attachments manually in a separate envelope
41-
// Because we do not support attachments in the feedback envelope
42-
// Once the Sentry API properly supports this, we can get rid of this and send it through the event envelope
43-
if (client && transport && dsn && attachments && attachments.length) {
44-
// TODO: https://docs.sentry.io/platforms/javascript/enriching-events/attachments/
45-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
46-
void transport.send(
47-
createAttachmentEnvelope(
48-
{
49-
...feedbackEvent,
50-
event_id: eventId,
51-
},
52-
attachments,
53-
dsn,
54-
client.getOptions()._metadata,
55-
client.getOptions().tunnel,
56-
),
57-
);
58-
}
59-
6037
return eventId;
6138
}

packages/core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export type { IntegrationIndex } from './integration';
88

99
export * from './tracing';
1010
export * from './semanticAttributes';
11-
export { createEventEnvelope, createSessionEnvelope, createAttachmentEnvelope, createSpanEnvelope } from './envelope';
11+
export { createEventEnvelope, createSessionEnvelope, createSpanEnvelope } from './envelope';
1212
export {
1313
captureCheckIn,
1414
withMonitor,

packages/core/test/lib/feedback.test.ts

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -152,29 +152,33 @@ describe('captureFeedback', () => {
152152
const attachment1 = new Uint8Array([1, 2, 3, 4, 5]);
153153
const attachment2 = new Uint8Array([6, 7, 8, 9]);
154154

155-
const eventId = captureFeedback({
156-
message: 'test',
157-
attachments: [
158-
{
159-
data: attachment1,
160-
filename: 'test-file.txt',
161-
},
162-
{
163-
data: attachment2,
164-
filename: 'test-file2.txt',
165-
},
166-
],
167-
});
155+
const eventId = captureFeedback(
156+
{
157+
message: 'test',
158+
},
159+
{
160+
attachments: [
161+
{
162+
data: attachment1,
163+
filename: 'test-file.txt',
164+
},
165+
{
166+
data: attachment2,
167+
filename: 'test-file2.txt',
168+
},
169+
],
170+
},
171+
);
168172

169173
await client.flush();
170174

171175
expect(typeof eventId).toBe('string');
172176

173-
expect(mockTransport).toHaveBeenCalledTimes(2);
177+
expect(mockTransport).toHaveBeenCalledTimes(1);
174178

175-
const [feedbackEnvelope, attachmentEnvelope] = mockTransport.mock.calls;
179+
const [feedbackEnvelope] = mockTransport.mock.calls;
176180

177-
// Feedback event is sent normally in one envelope
181+
expect(feedbackEnvelope).toHaveLength(1);
178182
expect(feedbackEnvelope[0]).toEqual([
179183
{
180184
event_id: eventId,
@@ -206,16 +210,6 @@ describe('captureFeedback', () => {
206210
type: 'feedback',
207211
},
208212
],
209-
],
210-
]);
211-
212-
// Attachments are sent in separate envelope
213-
expect(attachmentEnvelope[0]).toEqual([
214-
{
215-
event_id: eventId,
216-
sent_at: expect.any(String),
217-
},
218-
[
219213
[
220214
{
221215
type: 'attachment',
@@ -359,12 +353,6 @@ describe('captureFeedback', () => {
359353
trace: {
360354
trace_id: traceId,
361355
span_id: spanId,
362-
data: {
363-
'sentry.origin': 'manual',
364-
'sentry.sample_rate': 1,
365-
'sentry.source': 'custom',
366-
},
367-
origin: 'manual',
368356
},
369357
feedback: {
370358
message: 'test',

packages/feedback/src/core/sendFeedback.test.ts

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,6 @@ describe('sendFeedback', () => {
174174
trace: {
175175
span_id: expect.any(String),
176176
trace_id: expect.any(String),
177-
data: {
178-
'sentry.origin': 'manual',
179-
'sentry.sample_rate': 1,
180-
'sentry.source': 'custom',
181-
},
182-
origin: 'manual',
183177
},
184178
feedback: {
185179
contact_email: '[email protected]',
@@ -344,32 +338,35 @@ describe('sendFeedback', () => {
344338
const attachment1 = new Uint8Array([1, 2, 3, 4, 5]);
345339
const attachment2 = new Uint8Array([6, 7, 8, 9]);
346340

347-
const promise = sendFeedback({
348-
name: 'doe',
349-
350-
message: 'mi',
351-
attachments: [
352-
{
353-
data: attachment1,
354-
filename: 'test-file.txt',
355-
},
356-
{
357-
data: attachment2,
358-
filename: 'test-file2.txt',
359-
},
360-
],
361-
});
341+
const promise = sendFeedback(
342+
{
343+
name: 'doe',
344+
345+
message: 'mi',
346+
},
347+
{
348+
attachments: [
349+
{
350+
data: attachment1,
351+
filename: 'test-file.txt',
352+
},
353+
{
354+
data: attachment2,
355+
filename: 'test-file2.txt',
356+
},
357+
],
358+
},
359+
);
362360

363361
expect(promise).toBeInstanceOf(Promise);
364362

365363
const eventId = await promise;
366364

367365
expect(typeof eventId).toEqual('string');
368-
expect(mockTransport).toHaveBeenCalledTimes(2);
366+
expect(mockTransport).toHaveBeenCalledTimes(1);
369367

370-
const [feedbackEnvelope, attachmentEnvelope] = mockTransport.mock.calls;
368+
const [feedbackEnvelope] = mockTransport.mock.calls;
371369

372-
// Feedback event is sent normally in one envelope
373370
expect(feedbackEnvelope[0]).toEqual([
374371
{
375372
event_id: eventId,
@@ -405,16 +402,6 @@ describe('sendFeedback', () => {
405402
type: 'feedback',
406403
},
407404
],
408-
],
409-
]);
410-
411-
// Attachments are sent in separate envelope
412-
expect(attachmentEnvelope[0]).toEqual([
413-
{
414-
event_id: eventId,
415-
sent_at: expect.any(String),
416-
},
417-
[
418405
[
419406
{
420407
type: 'attachment',

packages/feedback/src/core/sendFeedback.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { captureFeedback } from '@sentry/core';
22
import { getClient } from '@sentry/core';
3-
import type { SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/types';
3+
import type { EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/types';
44
import type { Event } from '@sentry/types';
55
import { getLocationHref } from '@sentry/utils';
66
import { FEEDBACK_API_SOURCE } from '../constants';
@@ -10,7 +10,7 @@ import { FEEDBACK_API_SOURCE } from '../constants';
1010
*/
1111
export const sendFeedback: SendFeedback = (
1212
options: SendFeedbackParams,
13-
{ includeReplay = true } = {},
13+
hint: EventHint & { includeReplay?: boolean } = { includeReplay: true },
1414
): Promise<string> => {
1515
if (!options.message) {
1616
throw new Error('Unable to submit feedback with empty message');
@@ -29,7 +29,7 @@ export const sendFeedback: SendFeedback = (
2929
url: getLocationHref(),
3030
...options,
3131
},
32-
{ includeReplay },
32+
hint,
3333
);
3434

3535
// We want to wait for the feedback to be sent (or not)

packages/feedback/src/modal/components/Form.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,28 @@ export function Form({
112112
}
113113
const formData = new FormData(e.target);
114114
const attachment = await (screenshotInput && showScreenshotInput ? screenshotInput.value() : undefined);
115+
115116
const data: FeedbackFormData = {
116117
name: retrieveStringValue(formData, 'name'),
117118
email: retrieveStringValue(formData, 'email'),
118119
message: retrieveStringValue(formData, 'message'),
119120
attachments: attachment ? [attachment] : undefined,
120121
};
122+
121123
if (!hasAllRequiredFields(data)) {
122124
return;
123125
}
126+
124127
try {
125-
await onSubmit({ ...data, source: FEEDBACK_WIDGET_SOURCE });
128+
await onSubmit(
129+
{
130+
name: data.name,
131+
email: data.email,
132+
message: data.message,
133+
source: FEEDBACK_WIDGET_SOURCE,
134+
},
135+
{ attachments: data.attachments },
136+
);
126137
onSubmitSuccess(data);
127138
} catch (error) {
128139
DEBUG_BUILD && logger.error(error);

packages/types/src/feedback/sendFeedback.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import type { Attachment } from '../attachment';
2-
import type { Event } from '../event';
1+
import type { Event, EventHint } from '../event';
32
import type { User } from '../user';
43

54
/**
@@ -36,13 +35,12 @@ export interface SendFeedbackParams {
3635
message: string;
3736
name?: string;
3837
email?: string;
39-
attachments?: Attachment[];
4038
url?: string;
4139
source?: string;
4240
associatedEventId?: string;
4341
}
4442

45-
interface SendFeedbackOptions {
43+
interface SendFeedbackOptions extends EventHint {
4644
/**
4745
* Should include replay with the feedback?
4846
*/

0 commit comments

Comments
 (0)