@@ -10,91 +10,44 @@ import { prepareFeedbackEvent } from '../util/prepareFeedbackEvent';
1010export const sendFeedback : SendFeedback = (
1111 { name, email, message, attachments, source = FEEDBACK_API_SOURCE , url = getLocationHref ( ) } : SendFeedbackParams ,
1212 { includeReplay = true } = { } ,
13- ) = > {
13+ ) : Promise < void > {
1414 if ( ! message ) {
1515 throw new Error ( 'Unable to submit feedback with empty message' ) ;
1616 }
1717
18+ // We want to wait for the feedback to be sent (or not)
1819 const client = getClient ( ) ;
19- const transport = client && client . getTransport ( ) ;
20- const dsn = client && client . getDsn ( ) ;
2120
22- if ( ! client || ! transport || ! dsn ) {
23- throw new Error ( 'Invalid Sentry client' ) ;
21+ if ( ! client ) {
22+ throw new Error ( 'No client setup, cannot send feedback. ' ) ;
2423 }
2524
26- const baseEvent : FeedbackEvent = {
27- contexts : {
28- feedback : {
29- contact_email : email ,
30- name,
31- message,
32- url,
33- source,
34- } ,
35- } ,
36- type : 'feedback' ,
37- } ;
25+ const eventId = captureFeedback ( { name, email, message, attachments, source, url } , hint ) ;
3826
39- return withScope ( async scope => {
40- // No use for breadcrumbs in feedback
41- scope . clearBreadcrumbs ( ) ;
27+ // We want to wait for the feedback to be sent (or not)
28+ return new Promise < void > ( ( resolve , reject ) => {
29+ // After 5s, we want to clear anyhow
30+ const timeout = setTimeout ( ( ) => reject ( 'timeout' ) , 5_000 ) ;
4231
43- if ( [ FEEDBACK_API_SOURCE , FEEDBACK_WIDGET_SOURCE ] . includes ( String ( source ) ) ) {
44- scope . setLevel ( 'info' ) ;
45- }
46-
47- const feedbackEvent = await prepareFeedbackEvent ( {
48- scope,
49- client,
50- event : baseEvent ,
51- } ) ;
52-
53- if ( client . emit ) {
54- client . emit ( 'beforeSendFeedback' , feedbackEvent , { includeReplay : Boolean ( includeReplay ) } ) ;
55- }
56-
57- try {
58- const response = await transport . send (
59- createEventEnvelope ( feedbackEvent , dsn , client . getOptions ( ) . _metadata , client . getOptions ( ) . tunnel ) ,
60- ) ;
61-
62- if ( attachments && attachments . length ) {
63- // TODO: https://docs.sentry.io/platforms/javascript/enriching-events/attachments/
64- await transport . send (
65- createAttachmentEnvelope (
66- feedbackEvent ,
67- attachments ,
68- dsn ,
69- client . getOptions ( ) . _metadata ,
70- client . getOptions ( ) . tunnel ,
71- ) ,
72- ) ;
32+ client . on ( 'afterSendEvent' , ( event : Event , response : TransportMakeRequestResponse ) => {
33+ if ( event . event_id !== eventId ) {
34+ return ;
7335 }
7436
37+ clearTimeout ( timeout ) ;
38+
7539 // Require valid status codes, otherwise can assume feedback was not sent successfully
7640 if ( typeof response . statusCode === 'number' && ( response . statusCode < 200 || response . statusCode >= 300 ) ) {
7741 if ( response . statusCode === 0 ) {
78- throw new Error (
42+ return reject (
7943 'Unable to send Feedback. This is because of network issues, or because you are using an ad-blocker.' ,
8044 ) ;
8145 }
82- throw new Error ( 'Unable to send Feedback. Invalid response from server.' ) ;
46+ return reject ( 'Unable to send Feedback. Invalid response from server.' ) ;
8347 }
8448
85- return response ;
86- } catch ( err ) {
87- const error = new Error ( 'Unable to send Feedback' ) ;
88-
89- try {
90- // In case browsers don't allow this property to be writable
91- // @ts -expect-error This needs lib es2022 and newer
92- error . cause = err ;
93- } catch {
94- // nothing to do
95- }
96- throw error ;
97- }
49+ resolve ( ) ;
50+ } ) ;
9851 } ) ;
9952} ;
10053
0 commit comments