1- import { createEventEnvelope , getClient , withScope } from '@sentry/core' ;
1+ import { createEventEnvelope , getClient , withScope , createAttachmentEnvelope } from '@sentry/core' ;
22import type { FeedbackEvent , TransportMakeRequestResponse } from '@sentry/types' ;
33
44import { FEEDBACK_API_SOURCE , FEEDBACK_WIDGET_SOURCE } from '../constants' ;
5- import type { SendFeedbackData , SendFeedbackOptions } from '../types' ;
5+ import type { Screenshot , SendFeedbackData , SendFeedbackOptions } from '../types' ;
66import { prepareFeedbackEvent } from './prepareFeedbackEvent' ;
77
88/**
@@ -11,6 +11,7 @@ import { prepareFeedbackEvent } from './prepareFeedbackEvent';
1111export async function sendFeedbackRequest (
1212 { feedback : { message, email, name, source, url } } : SendFeedbackData ,
1313 { includeReplay = true } : SendFeedbackOptions = { } ,
14+ screenshots : Screenshot [ ] ,
1415) : Promise < void | TransportMakeRequestResponse > {
1516 const client = getClient ( ) ;
1617 const transport = client && client . getTransport ( ) ;
@@ -57,6 +58,19 @@ export async function sendFeedbackRequest(
5758
5859 const envelope = createEventEnvelope ( feedbackEvent , dsn , client . getOptions ( ) . _metadata , client . getOptions ( ) . tunnel ) ;
5960
61+ let attachment_envelope ;
62+ for ( const attachment of screenshots || [ ] ) {
63+ attachment_envelope = createAttachmentEnvelope (
64+ feedbackEvent ,
65+ attachment ,
66+ dsn ,
67+ client . getOptions ( ) . _metadata ,
68+ client . getOptions ( ) . tunnel ,
69+ // eslint-disable-next-line @sentry-internal/sdk/no-optional-chaining
70+ client . getOptions ( ) . transportOptions && client . getOptions ( ) . transportOptions ?. textEncoder ,
71+ ) ;
72+ }
73+
6074 let response : void | TransportMakeRequestResponse ;
6175
6276 try {
@@ -84,6 +98,33 @@ export async function sendFeedbackRequest(
8498 throw new Error ( 'Unable to send Feedback' ) ;
8599 }
86100
101+ if ( attachment_envelope ) {
102+ try {
103+ response = await transport . send ( attachment_envelope ) ;
104+ } catch ( err ) {
105+ const error = new Error ( 'Unable to send Feedback screenshot' ) ;
106+
107+ try {
108+ // In case browsers don't allow this property to be writable
109+ // @ts -expect-error This needs lib es2022 and newer
110+ error . cause = err ;
111+ } catch {
112+ // nothing to do
113+ }
114+ throw error ;
115+ }
116+
117+ // TODO (v8): we can remove this guard once transport.send's type signature doesn't include void anymore
118+ if ( ! response ) {
119+ return ;
120+ }
121+
122+ // Require valid status codes, otherwise can assume feedback was not sent successfully
123+ if ( typeof response . statusCode === 'number' && ( response . statusCode < 200 || response . statusCode >= 300 ) ) {
124+ throw new Error ( 'Unable to send Feedback screenshot' ) ;
125+ }
126+ }
127+
87128 return response ;
88129 } ) ;
89130}
0 commit comments