-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathfetch.ts
99 lines (90 loc) · 3.49 KB
/
fetch.ts
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { eventToSentryRequest, sessionToSentryRequest } from '@sentry/core';
import { Event, Response, SentryRequest, Session, TransportOptions } from '@sentry/types';
import { SentryError, supportsReferrerPolicy, SyncPromise } from '@sentry/utils';
import { BaseTransport } from './base';
import { FetchImpl, getNativeFetchImplementation } from './utils';
/** `fetch` based transport */
export class FetchTransport extends BaseTransport {
/**
* Fetch API reference which always points to native browser implementation.
*/
private _fetch: typeof fetch;
public constructor(options: TransportOptions, fetchImpl: FetchImpl = getNativeFetchImplementation()) {
super(options);
this._fetch = fetchImpl;
}
/**
* @inheritDoc
*/
public sendEvent(event: Event): PromiseLike<Response> {
return this._sendRequest(eventToSentryRequest(event, this._api), event);
}
/**
* @inheritDoc
*/
public sendSession(session: Session): PromiseLike<Response> {
return this._sendRequest(sessionToSentryRequest(session, this._api), session);
}
/**
* @param sentryRequest Prepared SentryRequest to be delivered
* @param originalPayload Original payload used to create SentryRequest
*/
private _sendRequest(sentryRequest: SentryRequest, originalPayload: Event | Session): PromiseLike<Response> {
if (this._isRateLimited(sentryRequest.type)) {
this.recordLostEvent('ratelimit_backoff', sentryRequest.type);
return Promise.reject({
event: originalPayload,
type: sentryRequest.type,
reason: `Transport for ${sentryRequest.type} requests locked till ${this._disabledUntil(
sentryRequest.type,
)} due to too many requests.`,
status: 429,
});
}
const options: RequestInit = {
body: sentryRequest.body,
method: 'POST',
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
// https://caniuse.com/#feat=referrer-policy
// It doesn't. And it throw exception instead of ignoring this parameter...
// REF: https://github.com/getsentry/raven-js/issues/1233
referrerPolicy: (supportsReferrerPolicy() ? 'origin' : '') as ReferrerPolicy,
};
if (this.options.fetchParameters !== undefined) {
Object.assign(options, this.options.fetchParameters);
}
if (this.options.headers !== undefined) {
options.headers = this.options.headers;
}
return this._buffer
.add(
() =>
new SyncPromise<Response>((resolve, reject) => {
void this._fetch(sentryRequest.url, options)
.then(response => {
const headers = {
'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),
'retry-after': response.headers.get('Retry-After'),
};
this._handleResponse({
requestType: sentryRequest.type,
response,
headers,
resolve,
reject,
});
})
.catch(reject);
}),
)
.then(undefined, reason => {
// It's either buffer rejection or any other xhr/fetch error, which are treated as NetworkError.
if (reason instanceof SentryError) {
this.recordLostEvent('queue_overflow', sentryRequest.type);
} else {
this.recordLostEvent('network_error', sentryRequest.type);
}
throw reason;
});
}
}