-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathfetch.ts
More file actions
69 lines (62 loc) · 2.88 KB
/
fetch.ts
File metadata and controls
69 lines (62 loc) · 2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import type { Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core';
import { createTransport, makePromiseBuffer } from '@sentry/core';
import { clearCachedImplementation, getNativeImplementation } from '@sentry-internal/browser-utils';
import type { WINDOW } from '../helpers';
import type { BrowserTransportOptions } from './types';
const DEFAULT_BROWSER_TRANSPORT_BUFFER_SIZE = 40;
/**
* Creates a Transport that uses the Fetch API to send events to Sentry.
*/
export function makeFetchTransport(
options: BrowserTransportOptions,
nativeFetch: typeof WINDOW.fetch = getNativeImplementation('fetch'),
): Transport {
let pendingBodySize = 0;
let pendingCount = 0;
async function makeRequest(request: TransportRequest): Promise<TransportMakeRequestResponse> {
const requestSize = request.body.length;
pendingBodySize += requestSize;
pendingCount++;
const requestOptions: RequestInit = {
body: request.body as BodyInit,
method: 'POST',
referrerPolicy: 'strict-origin',
headers: options.headers,
// Outgoing requests are usually cancelled when navigating to a different page, causing a "TypeError: Failed to
// fetch" error and sending a "network_error" client-outcome - in Chrome, the request status shows "(cancelled)".
// The `keepalive` flag keeps outgoing requests alive, even when switching pages. We want this since we're
// frequently sending events right before the user is switching pages (eg. when finishing navigation transactions).
// Gotchas:
// - `keepalive` isn't supported by Firefox
// - As per spec (https://fetch.spec.whatwg.org/#http-network-or-cache-fetch):
// If the sum of contentLength and inflightKeepaliveBytes is greater than 64 kibibytes, then return a network error.
// We will therefore only activate the flag when we're below that limit.
// There is also a limit of requests that can be open at the same time, so we also limit this to 15
// See https://github.com/getsentry/sentry-javascript/pull/7553 for details
keepalive: pendingBodySize <= 60_000 && pendingCount < 15,
...options.fetchOptions,
};
try {
// Note: We do not need to suppress tracing here, because we are using the native fetch, instead of our wrapped one.
const response = await nativeFetch(options.url, requestOptions);
return {
statusCode: response.status,
headers: {
'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),
'retry-after': response.headers.get('Retry-After'),
},
};
} catch (e) {
clearCachedImplementation('fetch');
throw e;
} finally {
pendingBodySize -= requestSize;
pendingCount--;
}
}
return createTransport(
options,
makeRequest,
makePromiseBuffer(options.bufferSize || DEFAULT_BROWSER_TRANSPORT_BUFFER_SIZE),
);
}