UNPKG

5.32 kBJavaScriptView Raw
1Object.defineProperty(exports, "__esModule", { value: true });
2var tslib_1 = require("tslib");
3var core_1 = require("@sentry/core");
4var types_1 = require("@sentry/types");
5var utils_1 = require("@sentry/utils");
6var CATEGORY_MAPPING = {
7 event: 'error',
8 transaction: 'transaction',
9 session: 'session',
10 attachment: 'attachment',
11};
12/** Base Transport class implementation */
13var BaseTransport = /** @class */ (function () {
14 function BaseTransport(options) {
15 this.options = options;
16 /** A simple buffer holding all requests. */
17 this._buffer = new utils_1.PromiseBuffer(30);
18 /** Locks transport after receiving rate limits in a response */
19 this._rateLimits = {};
20 this._api = new core_1.API(options.dsn, options._metadata);
21 // eslint-disable-next-line deprecation/deprecation
22 this.url = this._api.getStoreEndpointWithUrlEncodedAuth();
23 }
24 /**
25 * @inheritDoc
26 */
27 BaseTransport.prototype.sendEvent = function (_) {
28 throw new utils_1.SentryError('Transport Class has to implement `sendEvent` method');
29 };
30 /**
31 * @inheritDoc
32 */
33 BaseTransport.prototype.close = function (timeout) {
34 return this._buffer.drain(timeout);
35 };
36 /**
37 * Handle Sentry repsonse for promise-based transports.
38 */
39 BaseTransport.prototype._handleResponse = function (_a) {
40 var requestType = _a.requestType, response = _a.response, headers = _a.headers, resolve = _a.resolve, reject = _a.reject;
41 var status = types_1.Status.fromHttpCode(response.status);
42 /**
43 * "The name is case-insensitive."
44 * https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
45 */
46 var limited = this._handleRateLimit(headers);
47 if (limited)
48 utils_1.logger.warn("Too many requests, backing off until: " + this._disabledUntil(requestType));
49 if (status === types_1.Status.Success) {
50 resolve({ status: status });
51 return;
52 }
53 reject(response);
54 };
55 /**
56 * Gets the time that given category is disabled until for rate limiting
57 */
58 BaseTransport.prototype._disabledUntil = function (requestType) {
59 var category = CATEGORY_MAPPING[requestType];
60 return this._rateLimits[category] || this._rateLimits.all;
61 };
62 /**
63 * Checks if a category is rate limited
64 */
65 BaseTransport.prototype._isRateLimited = function (requestType) {
66 return this._disabledUntil(requestType) > new Date(Date.now());
67 };
68 /**
69 * Sets internal _rateLimits from incoming headers. Returns true if headers contains a non-empty rate limiting header.
70 */
71 BaseTransport.prototype._handleRateLimit = function (headers) {
72 var e_1, _a, e_2, _b;
73 var now = Date.now();
74 var rlHeader = headers['x-sentry-rate-limits'];
75 var raHeader = headers['retry-after'];
76 if (rlHeader) {
77 try {
78 // rate limit headers are of the form
79 // <header>,<header>,..
80 // where each <header> is of the form
81 // <retry_after>: <categories>: <scope>: <reason_code>
82 // where
83 // <retry_after> is a delay in ms
84 // <categories> is the event type(s) (error, transaction, etc) being rate limited and is of the form
85 // <category>;<category>;...
86 // <scope> is what's being limited (org, project, or key) - ignored by SDK
87 // <reason_code> is an arbitrary string like "org_quota" - ignored by SDK
88 for (var _c = tslib_1.__values(rlHeader.trim().split(',')), _d = _c.next(); !_d.done; _d = _c.next()) {
89 var limit = _d.value;
90 var parameters = limit.split(':', 2);
91 var headerDelay = parseInt(parameters[0], 10);
92 var delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default
93 try {
94 for (var _e = (e_2 = void 0, tslib_1.__values(parameters[1].split(';'))), _f = _e.next(); !_f.done; _f = _e.next()) {
95 var category = _f.value;
96 this._rateLimits[category || 'all'] = new Date(now + delay);
97 }
98 }
99 catch (e_2_1) { e_2 = { error: e_2_1 }; }
100 finally {
101 try {
102 if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
103 }
104 finally { if (e_2) throw e_2.error; }
105 }
106 }
107 }
108 catch (e_1_1) { e_1 = { error: e_1_1 }; }
109 finally {
110 try {
111 if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
112 }
113 finally { if (e_1) throw e_1.error; }
114 }
115 return true;
116 }
117 else if (raHeader) {
118 this._rateLimits.all = new Date(now + utils_1.parseRetryAfterHeader(now, raHeader));
119 return true;
120 }
121 return false;
122 };
123 return BaseTransport;
124}());
125exports.BaseTransport = BaseTransport;
126//# sourceMappingURL=base.js.map
\No newline at end of file