Skip to content

Commit 29f92e6

Browse files
logaretmclaude
andcommitted
feat(feedback)!: always reject sendFeedback with an Error
Previously, sendFeedback's async rejection paths (timeout, 403, generic transport error) rejected with plain strings, while the sync-throw paths used Error instances. Unify on Error for all paths so consumers can rely on a consistent rejection shape. BREAKING CHANGE: sendFeedback now always rejects with an Error whose .message is the error code (ERROR_TIMEOUT, ERROR_FORBIDDEN, or ERROR_GENERIC). Previously these paths rejected with the raw string. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 70d2ab4 commit 29f92e6

3 files changed

Lines changed: 8 additions & 9 deletions

File tree

packages/feedback/src/core/sendFeedback.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { Event, EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/core';
22
import { captureFeedback, getClient, getCurrentScope, getLocationHref } from '@sentry/core';
33
import { FEEDBACK_API_SOURCE } from '../constants';
4-
import type { FeedbackErrorCode } from '../util/createFeedbackError';
54
import { createFeedbackError } from '../util/createFeedbackError';
65

76
/**
@@ -37,7 +36,7 @@ export const sendFeedback: SendFeedback = (
3736
// We want to wait for the feedback to be sent (or not)
3837
return new Promise<string>((resolve, reject) => {
3938
// After 30s, we want to clear anyhow
40-
const timeout = setTimeout(() => reject('ERROR_TIMEOUT' satisfies FeedbackErrorCode), 30_000);
39+
const timeout = setTimeout(() => reject(createFeedbackError('ERROR_TIMEOUT')), 30_000);
4140

4241
const cleanup = client.on('afterSendEvent', (event: Event, response: TransportMakeRequestResponse) => {
4342
if (event.event_id !== eventId) {
@@ -53,10 +52,10 @@ export const sendFeedback: SendFeedback = (
5352
}
5453

5554
if (response?.statusCode === 403) {
56-
return reject('ERROR_FORBIDDEN' satisfies FeedbackErrorCode);
55+
return reject(createFeedbackError('ERROR_FORBIDDEN'));
5756
}
5857

59-
return reject('ERROR_GENERIC' satisfies FeedbackErrorCode);
58+
return reject(createFeedbackError('ERROR_GENERIC'));
6059
});
6160
});
6261
};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export function Form({
145145
onSubmitSuccess(data, eventId);
146146
} catch (error) {
147147
DEBUG_BUILD && debug.error(error);
148-
const err = error instanceof Error ? error : new Error(String(error));
148+
const err = error as Error;
149149
setError(errorTextByCode[err.message as FeedbackErrorCode] || errorGenericText);
150150
onSubmitError(err);
151151
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ describe('sendFeedback', () => {
279279
email: 're@example.org',
280280
message: 'mi',
281281
}),
282-
).rejects.toMatch('ERROR_GENERIC');
282+
).rejects.toThrow('ERROR_GENERIC');
283283
});
284284

285285
it('handles 0 transport error', async () => {
@@ -294,7 +294,7 @@ describe('sendFeedback', () => {
294294
email: 're@example.org',
295295
message: 'mi',
296296
}),
297-
).rejects.toMatch('ERROR_GENERIC');
297+
).rejects.toThrow('ERROR_GENERIC');
298298
});
299299

300300
it('handles 403 transport error', async () => {
@@ -309,7 +309,7 @@ describe('sendFeedback', () => {
309309
email: 're@example.org',
310310
message: 'mi',
311311
}),
312-
).rejects.toMatch('ERROR_FORBIDDEN');
312+
).rejects.toThrow('ERROR_FORBIDDEN');
313313
});
314314

315315
it('handles 200 transport response', async () => {
@@ -343,7 +343,7 @@ describe('sendFeedback', () => {
343343

344344
vi.advanceTimersByTime(30_000);
345345

346-
await expect(promise).rejects.toMatch('ERROR_TIMEOUT');
346+
await expect(promise).rejects.toThrow('ERROR_TIMEOUT');
347347

348348
vi.useRealTimers();
349349
});

0 commit comments

Comments
 (0)