Skip to content

Commit b0752b5

Browse files
authored
feat(v8/browser): Remove XHR transport (#10703)
resolves #5927 Removes `makeXHRTransport` and makes the fetch transport the default one. I've also added a warning warning to browser client init that states that the sentry browser sdk requires the fetch API to function.
1 parent c2baeac commit b0752b5

File tree

10 files changed

+57
-162
lines changed

10 files changed

+57
-162
lines changed

MIGRATION.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ to access and mutate the current scope.
9090

9191
`@sentry/hub` has been removed. All exports from `@sentry.hub` should be available in `@sentry/core`.
9292

93+
## Removal of `makeXHRTransport` transport (#10703)
94+
95+
The `makeXHRTransport` transport has been removed. Only `makeFetchTransport` is available now. This means that the
96+
Sentry SDK requires the fetch API to be available in the environment.
97+
9398
## General API Changes
9499

95100
- The minumum supported Node version for all the SDK packages is Node 14 (#10527)

dev-packages/browser-integration-tests/suites/replay/errors/errorModeCustomTransport/init.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Sentry.init({
1414
replaysOnErrorSampleRate: 1.0,
1515
integrations: [window.Replay],
1616
transport: options => {
17-
const transport = new Sentry.makeXHRTransport(options);
17+
const transport = new Sentry.makeFetchTransport(options);
1818

1919
delete transport.send.__sentry__baseTransport__;
2020

packages/browser/src/exports.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export * from './metrics';
8282

8383
export { WINDOW } from './helpers';
8484
export { BrowserClient } from './client';
85-
export { makeFetchTransport, makeXHRTransport } from './transports';
85+
export { makeFetchTransport } from './transports/fetch';
8686
export {
8787
defaultStackParser,
8888
defaultStackLineParsers,

packages/browser/src/sdk.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { httpContextIntegration } from './integrations/httpcontext';
2727
import { linkedErrorsIntegration } from './integrations/linkederrors';
2828
import { browserApiErrorsIntegration } from './integrations/trycatch';
2929
import { defaultStackParser } from './stack-parsers';
30-
import { makeFetchTransport, makeXHRTransport } from './transports';
30+
import { makeFetchTransport } from './transports/fetch';
3131

3232
/** Get the default integrations for the browser SDK. */
3333
export function getDefaultIntegrations(_options: Options): Integration[] {
@@ -116,11 +116,18 @@ export function init(options: BrowserOptions = {}): void {
116116
options.sendClientReports = true;
117117
}
118118

119+
if (DEBUG_BUILD) {
120+
if (!supportsFetch()) {
121+
logger.warn(
122+
'No Fetch API detected. The Sentry SDK requires a Fetch API compatible environment to send events. Please add a Fetch API polyfill.',
123+
);
124+
}
125+
}
119126
const clientOptions: BrowserClientOptions = {
120127
...options,
121128
stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),
122129
integrations: getIntegrationsToSetup(options),
123-
transport: options.transport || (supportsFetch() ? makeFetchTransport : makeXHRTransport),
130+
transport: options.transport || makeFetchTransport,
124131
};
125132

126133
initAndBind(BrowserClient, clientOptions);

packages/browser/src/transports/fetch.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { clearCachedFetchImplementation, getNativeFetchImplementation } from './
1111
*/
1212
export function makeFetchTransport(
1313
options: BrowserTransportOptions,
14-
nativeFetch: FetchImpl = getNativeFetchImplementation(),
14+
nativeFetch: FetchImpl | undefined = getNativeFetchImplementation(),
1515
): Transport {
1616
let pendingBodySize = 0;
1717
let pendingCount = 0;
@@ -41,6 +41,11 @@ export function makeFetchTransport(
4141
...options.fetchOptions,
4242
};
4343

44+
if (!nativeFetch) {
45+
clearCachedFetchImplementation();
46+
return rejectedSyncPromise('No fetch implementation available');
47+
}
48+
4449
try {
4550
return nativeFetch(options.url, requestOptions).then(response => {
4651
pendingBodySize -= requestSize;

packages/browser/src/transports/index.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/browser/src/transports/utils.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export type FetchImpl = typeof fetch;
4545
* Firefox: NetworkError when attempting to fetch resource
4646
* Safari: resource blocked by content blocker
4747
*/
48-
export function getNativeFetchImplementation(): FetchImpl {
48+
export function getNativeFetchImplementation(): FetchImpl | undefined {
4949
if (cachedFetchImpl) {
5050
return cachedFetchImpl;
5151
}
@@ -75,7 +75,13 @@ export function getNativeFetchImplementation(): FetchImpl {
7575
}
7676
}
7777

78-
return (cachedFetchImpl = fetchImpl.bind(WINDOW));
78+
try {
79+
return (cachedFetchImpl = fetchImpl.bind(WINDOW));
80+
} catch (e) {
81+
// empty
82+
}
83+
84+
return undefined;
7985
/* eslint-enable @typescript-eslint/unbound-method */
8086
}
8187

packages/browser/src/transports/xhr.ts

Lines changed: 0 additions & 52 deletions
This file was deleted.

packages/browser/test/unit/transports/xhr.test.ts

Lines changed: 0 additions & 99 deletions
This file was deleted.

packages/vue/test/integration/VueIntegration.test.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,23 @@ describe('Sentry.VueIntegration', () => {
1010
let loggerWarnings: unknown[] = [];
1111
let warnings: unknown[] = [];
1212

13+
const globalFetch = globalThis.fetch;
14+
const globalResponse = globalThis.Response;
15+
const globalRequest = globalThis.Request;
16+
17+
beforeAll(() => {
18+
globalThis.fetch = jest.fn();
19+
// @ts-expect-error This is a mock
20+
globalThis.Response = jest.fn();
21+
globalThis.Request = jest.fn();
22+
});
23+
24+
afterAll(() => {
25+
globalThis.fetch = globalFetch;
26+
globalThis.Response = globalResponse;
27+
globalThis.Request = globalRequest;
28+
});
29+
1330
beforeEach(() => {
1431
warnings = [];
1532
loggerWarnings = [];
@@ -28,7 +45,11 @@ describe('Sentry.VueIntegration', () => {
2845
});
2946

3047
it('allows to initialize integration later', () => {
31-
Sentry.init({ dsn: PUBLIC_DSN, defaultIntegrations: false, autoSessionTracking: false });
48+
Sentry.init({
49+
dsn: PUBLIC_DSN,
50+
defaultIntegrations: false,
51+
autoSessionTracking: false,
52+
});
3253

3354
const el = document.createElement('div');
3455
const app = createApp({
@@ -48,7 +69,11 @@ describe('Sentry.VueIntegration', () => {
4869
});
4970

5071
it('warns when mounting before SDK.VueIntegration', () => {
51-
Sentry.init({ dsn: PUBLIC_DSN, defaultIntegrations: false, autoSessionTracking: false });
72+
Sentry.init({
73+
dsn: PUBLIC_DSN,
74+
defaultIntegrations: false,
75+
autoSessionTracking: false,
76+
});
5277

5378
const el = document.createElement('div');
5479
const app = createApp({

0 commit comments

Comments
 (0)