/
xhr.ts
76 lines (68 loc) · 2.7 KB
/
xhr.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
import { eventToSentryRequest, sessionToSentryRequest } from '@sentry/core';
import { Event, Outcome, Response, SentryRequest, Session } from '@sentry/types';
import { SentryError, SyncPromise } from '@sentry/utils';
import { BaseTransport } from './base';
/** `XHR` based transport */
export class XHRTransport extends BaseTransport {
/**
* @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(Outcome.RateLimitBackoff, 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,
});
}
return this._buffer
.add(
() =>
new SyncPromise<Response>((resolve, reject) => {
const request = new XMLHttpRequest();
request.onreadystatechange = (): void => {
if (request.readyState === 4) {
const headers = {
'x-sentry-rate-limits': request.getResponseHeader('X-Sentry-Rate-Limits'),
'retry-after': request.getResponseHeader('Retry-After'),
};
this._handleResponse({ requestType: sentryRequest.type, response: request, headers, resolve, reject });
}
};
request.open('POST', sentryRequest.url);
for (const header in this.options.headers) {
if (this.options.headers.hasOwnProperty(header)) {
request.setRequestHeader(header, this.options.headers[header]);
}
}
request.send(sentryRequest.body);
}),
)
.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(Outcome.QueueOverflow, sentryRequest.type);
} else {
this.recordLostEvent(Outcome.NetworkError, sentryRequest.type);
}
throw reason;
});
}
}