Skip to content

Commit d814f8c

Browse files
committed
feat: send feedback envelopes using captureEvent
1 parent 4f14f26 commit d814f8c

File tree

5 files changed

+51
-143
lines changed

5 files changed

+51
-143
lines changed

packages/feedback/src/types/index.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,10 @@
1-
import type { Event, Primitive } from '@sentry/types';
1+
import type { Primitive } from '@sentry/types';
22

33
import type { ActorComponent } from '../widget/Actor';
44
import type { DialogComponent } from '../widget/Dialog';
55

66
export type SentryTags = { [key: string]: Primitive } | undefined;
77

8-
/**
9-
* NOTE: These types are still considered Beta and subject to change.
10-
* @hidden
11-
*/
12-
export interface FeedbackEvent extends Event {
13-
feedback: {
14-
message: string;
15-
url: string;
16-
contact_email?: string;
17-
name?: string;
18-
replay_id?: string;
19-
};
20-
// TODO: Add this event type to Event
21-
// type: 'feedback_event';
22-
}
23-
248
export interface SendFeedbackData {
259
feedback: {
2610
message: string;

packages/feedback/src/util/handleFeedbackSubmit.ts

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,34 @@ import type { DialogComponent } from '../widget/Dialog';
55
/**
66
* Calls `sendFeedback` to send feedback, handles UI behavior of dialog.
77
*/
8-
export async function handleFeedbackSubmit(
8+
export function handleFeedbackSubmit(
99
dialog: DialogComponent | null,
1010
feedback: FeedbackFormData,
1111
options?: SendFeedbackOptions,
12-
): Promise<Response | false> {
12+
): string | undefined {
1313
if (!dialog) {
1414
// Not sure when this would happen
15-
return false;
15+
return;
1616
}
1717

18-
const showFetchError = (): void => {
19-
if (!dialog) {
20-
return;
21-
}
22-
dialog.showError('There was a problem submitting feedback, please wait and try again.');
23-
};
18+
// const showFetchError = (): void => {
19+
// if (!dialog) {
20+
// return;
21+
// }
22+
// dialog.showError('There was a problem submitting feedback, please wait and try again.');
23+
// };
2424

25-
try {
26-
dialog.hideError();
27-
const resp = await sendFeedback(feedback, options);
25+
dialog.hideError();
2826

29-
if (!resp) {
30-
// Errored... re-enable submit button
31-
showFetchError();
32-
return false;
33-
}
34-
35-
// Success!
36-
return resp;
37-
} catch {
38-
// Errored... re-enable submit button
39-
showFetchError();
40-
return false;
41-
}
27+
// TODO: Error handling?
28+
return sendFeedback(feedback, options);
29+
// try {
30+
// const resp = await sendFeedback(feedback, options);
31+
//
32+
// // Success!
33+
// return resp;
34+
// } catch {
35+
// // Errored... re-enable submit button
36+
// showFetchError();
37+
// }
4238
}

packages/feedback/src/util/prepareFeedbackEvent.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import type { Scope } from '@sentry/core';
22
import { prepareEvent } from '@sentry/core';
3-
import type { Client } from '@sentry/types';
4-
5-
import type { FeedbackEvent } from '../types';
3+
import type { Client, FeedbackEvent } from '@sentry/types';
64

75
interface PrepareFeedbackEventParams {
86
client: Client;
@@ -11,13 +9,15 @@ interface PrepareFeedbackEventParams {
119
}
1210
/**
1311
* Prepare a feedback event & enrich it with the SDK metadata.
12+
*
13+
* TODO: Refactor this with the replay version
1414
*/
1515
export async function prepareFeedbackEvent({
1616
client,
1717
scope,
1818
event,
1919
}: PrepareFeedbackEventParams): Promise<FeedbackEvent | null> {
20-
const eventHint = { integrations: undefined };
20+
const eventHint = {};
2121
if (client.emit) {
2222
client.emit('preprocessEvent', event, eventHint);
2323
}
@@ -44,9 +44,9 @@ export async function prepareFeedbackEvent({
4444
const { name, version } = (metadata && metadata.sdk) || {};
4545

4646
preparedEvent.sdk = {
47-
...preparedEvent.sdk,
4847
name: name || 'sentry.javascript.unknown',
4948
version: version || '0.0.0',
5049
};
50+
5151
return preparedEvent;
5252
}
Lines changed: 22 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,41 @@
11
import { getCurrentHub } from '@sentry/core';
2-
import { dsnToString } from '@sentry/utils';
2+
import type { FeedbackEvent } from '@sentry/types';
3+
import { uuid4 } from '@sentry/utils';
34

45
import type { SendFeedbackData } from '../types';
5-
import { prepareFeedbackEvent } from './prepareFeedbackEvent';
66

77
/**
88
* Send feedback using `fetch()`
99
*/
10-
export async function sendFeedbackRequest({
10+
export function sendFeedbackRequest({
1111
feedback: { message, email, name, replay_id, url },
12-
}: SendFeedbackData): Promise<Response | null> {
12+
}: SendFeedbackData): string | undefined {
1313
const hub = getCurrentHub();
14-
15-
if (!hub) {
16-
return null;
17-
}
18-
1914
const client = hub.getClient();
2015
const scope = hub.getScope();
21-
const transport = client && client.getTransport();
22-
const dsn = client && client.getDsn();
2316

24-
if (!client || !transport || !dsn) {
25-
return null;
17+
if (!client) {
18+
return;
2619
}
2720

28-
const baseEvent = {
29-
feedback: {
30-
contact_email: email,
31-
name,
32-
message,
33-
replay_id,
34-
url,
21+
const baseEvent: FeedbackEvent = {
22+
contexts: {
23+
feedback: {
24+
contact_email: email,
25+
name,
26+
message,
27+
replay_id,
28+
url,
29+
},
3530
},
36-
// type: 'feedback_event',
31+
type: 'feedback',
3732
};
3833

39-
const feedbackEvent = await prepareFeedbackEvent({
34+
return client.captureEvent(
35+
baseEvent,
36+
{
37+
event_id: uuid4(),
38+
},
4039
scope,
41-
client,
42-
event: baseEvent,
43-
});
44-
45-
if (!feedbackEvent) {
46-
// Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions
47-
// client.recordDroppedEvent('event_processor', 'feedback', baseEvent);
48-
return null;
49-
}
50-
51-
/*
52-
For reference, the fully built event looks something like this:
53-
{
54-
"data": {
55-
"dist": "abc123",
56-
"environment": "production",
57-
"feedback": {
58-
"contact_email": "colton.allen@sentry.io",
59-
"message": "I really like this user-feedback feature!",
60-
"replay_id": "ec3b4dc8b79f417596f7a1aa4fcca5d2",
61-
"url": "https://docs.sentry.io/platforms/javascript/"
62-
},
63-
"id": "1ffe0775ac0f4417aed9de36d9f6f8dc",
64-
"platform": "javascript",
65-
"release": "[email protected]",
66-
"request": {
67-
"headers": {
68-
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
69-
}
70-
},
71-
"sdk": {
72-
"name": "sentry.javascript.react",
73-
"version": "6.18.1"
74-
},
75-
"tags": {
76-
"key": "value"
77-
},
78-
"timestamp": "2023-08-31T14:10:34.954048",
79-
"user": {
80-
"email": "username@example.com",
81-
"id": "123",
82-
"ip_address": "127.0.0.1",
83-
"name": "user",
84-
"username": "user2270129"
85-
}
86-
}
87-
}
88-
*/
89-
90-
// Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to
91-
// sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may
92-
// 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
93-
// of this `delete`, lest we miss putting it back in the next time the property is in use.)
94-
delete feedbackEvent.sdkProcessingMetadata;
95-
96-
try {
97-
const path = 'https://sentry.io/api/0/feedback/';
98-
const response = await fetch(path, {
99-
method: 'POST',
100-
headers: {
101-
'Content-Type': 'application/json',
102-
Authorization: `DSN ${dsnToString(dsn)}`,
103-
},
104-
body: JSON.stringify(feedbackEvent),
105-
});
106-
if (!response.ok) {
107-
return null;
108-
}
109-
return response;
110-
} catch (err) {
111-
return null;
112-
}
40+
);
11341
}

packages/feedback/src/widget/createWidget.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ export function createWidget({ shadow, options, attachTo }: CreateWidgetParams):
7474
return;
7575
}
7676

77-
const result = await handleFeedbackSubmit(dialog, feedback);
77+
const eventId = handleFeedbackSubmit(dialog, feedback);
7878

7979
// Error submitting feedback
80-
if (!result) {
80+
if (!eventId) {
8181
if (options.onSubmitError) {
8282
options.onSubmitError();
8383
}

0 commit comments

Comments
 (0)