1
- import { getCurrentHub } from '@sentry/core' ;
2
- import type { FeedbackEvent } from '@sentry/types' ;
3
- import { uuid4 } from '@sentry/utils' ;
1
+ import { createEventEnvelope , getCurrentHub } from '@sentry/core' ;
2
+ import type { FeedbackEvent , TransportMakeRequestResponse } from '@sentry/types' ;
4
3
5
4
import type { SendFeedbackData } from '../types' ;
5
+ import { prepareFeedbackEvent } from './prepareFeedbackEvent' ;
6
6
7
7
/**
8
- * Send feedback using `fetch()`
8
+ * Send feedback using transport
9
9
*/
10
- export function sendFeedbackRequest ( {
10
+ export async function sendFeedbackRequest ( {
11
11
feedback : { message, email, name, replay_id, url } ,
12
- } : SendFeedbackData ) : string | undefined {
12
+ } : SendFeedbackData ) : Promise < void | TransportMakeRequestResponse > {
13
+ debugger ;
13
14
const hub = getCurrentHub ( ) ;
14
15
const client = hub . getClient ( ) ;
15
16
const scope = hub . getScope ( ) ;
17
+ const transport = client && client . getTransport ( ) ;
18
+ const dsn = client && client . getDsn ( ) ;
16
19
17
- if ( ! client ) {
20
+ if ( ! client || ! transport || ! dsn ) {
18
21
return ;
19
22
}
20
23
@@ -31,11 +34,87 @@ export function sendFeedbackRequest({
31
34
type : 'feedback' ,
32
35
} ;
33
36
34
- return client . captureEvent (
35
- baseEvent ,
36
- {
37
- event_id : uuid4 ( ) ,
38
- } ,
37
+ const feedbackEvent = await prepareFeedbackEvent ( {
39
38
scope,
40
- ) ;
39
+ client,
40
+ event : baseEvent ,
41
+ } ) ;
42
+
43
+ if ( feedbackEvent === null ) {
44
+ return ;
45
+ }
46
+
47
+ /*
48
+ For reference, the fully built event looks something like this:
49
+ {
50
+ "type": "feedback",
51
+ "event_id": "d2132d31b39445f1938d7e21b6bf0ec4",
52
+ "timestamp": 1597977777.6189718,
53
+ "dist": "1.12",
54
+ "platform": "javascript",
55
+ "environment": "production",
56
+ "release": 42,
57
+ "tags": {"transaction": "/organizations/:orgId/performance/:eventSlug/"},
58
+ "sdk": {"name": "name", "version": "version"},
59
+ "user": {
60
+ "id": "123",
61
+ "username": "user",
62
+ "email": "user@site .com",
63
+ "ip_address": "192.168.11.12",
64
+ },
65
+ "request": {
66
+ "url": None,
67
+ "headers": {
68
+ "user-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15"
69
+ },
70
+ },
71
+ "contexts": {
72
+ "feedback": {
73
+ "message": "test message",
74
+ "contact_email": "test@example .com",
75
+ "type": "feedback",
76
+ },
77
+ "trace": {
78
+ "trace_id": "4C79F60C11214EB38604F4AE0781BFB2",
79
+ "span_id": "FA90FDEAD5F74052",
80
+ "type": "trace",
81
+ },
82
+ "replay": {
83
+ "replay_id": "e2d42047b1c5431c8cba85ee2a8ab25d",
84
+ },
85
+ },
86
+ }
87
+ */
88
+
89
+ const envelope = createEventEnvelope ( feedbackEvent , dsn , client . getOptions ( ) . _metadata , client . getOptions ( ) . tunnel ) ;
90
+
91
+ let response : void | TransportMakeRequestResponse ;
92
+
93
+ try {
94
+ console . log ( envelope ) ;
95
+ response = await transport . send ( envelope ) ;
96
+ } catch ( err ) {
97
+ const error = new Error ( 'Unable to send Feedback' ) ;
98
+
99
+ try {
100
+ // In case browsers don't allow this property to be writable
101
+ // @ts -expect-error This needs lib es2022 and newer
102
+ error . cause = err ;
103
+ } catch {
104
+ // nothing to do
105
+ }
106
+ throw error ;
107
+ }
108
+
109
+ // TODO (v8): we can remove this guard once transport.send's type signature doesn't include void anymore
110
+ if ( ! response ) {
111
+ return response ;
112
+ }
113
+
114
+ // If the status code is invalid, we want to immediately stop & not retry
115
+ if ( typeof response . statusCode === 'number' && ( response . statusCode < 200 || response . statusCode >= 300 ) ) {
116
+ throw new Error ( 'Unable to send Feedback' ) ;
117
+ }
118
+
119
+ return response ;
41
120
}
0 commit comments