UNPKG

5.87 kBJavaScriptView Raw
1Object.defineProperty(exports, "__esModule", { value: true });
2var tslib_1 = require("tslib");
3var core_1 = require("@sentry/core");
4var utils_1 = require("@sentry/utils");
5var flags_1 = require("../flags");
6var utils_2 = require("./utils");
7function requestTypeToCategory(ty) {
8 var tyStr = ty;
9 return tyStr === 'event' ? 'error' : tyStr;
10}
11var global = utils_1.getGlobalObject();
12/** Base Transport class implementation */
13var BaseTransport = /** @class */ (function () {
14 function BaseTransport(options) {
15 var _this = this;
16 this.options = options;
17 /** A simple buffer holding all requests. */
18 this._buffer = utils_1.makePromiseBuffer(30);
19 /** Locks transport after receiving rate limits in a response */
20 this._rateLimits = {};
21 this._outcomes = {};
22 this._api = core_1.initAPIDetails(options.dsn, options._metadata, options.tunnel);
23 // eslint-disable-next-line deprecation/deprecation
24 this.url = core_1.getStoreEndpointWithUrlEncodedAuth(this._api.dsn);
25 if (this.options.sendClientReports && global.document) {
26 global.document.addEventListener('visibilitychange', function () {
27 if (global.document.visibilityState === 'hidden') {
28 _this._flushOutcomes();
29 }
30 });
31 }
32 }
33 /**
34 * @inheritDoc
35 */
36 BaseTransport.prototype.sendEvent = function (event) {
37 return this._sendRequest(core_1.eventToSentryRequest(event, this._api), event);
38 };
39 /**
40 * @inheritDoc
41 */
42 BaseTransport.prototype.sendSession = function (session) {
43 return this._sendRequest(core_1.sessionToSentryRequest(session, this._api), session);
44 };
45 /**
46 * @inheritDoc
47 */
48 BaseTransport.prototype.close = function (timeout) {
49 return this._buffer.drain(timeout);
50 };
51 /**
52 * @inheritDoc
53 */
54 BaseTransport.prototype.recordLostEvent = function (reason, category) {
55 var _a;
56 if (!this.options.sendClientReports) {
57 return;
58 }
59 // We want to track each category (event, transaction, session) separately
60 // but still keep the distinction between different type of outcomes.
61 // We could use nested maps, but it's much easier to read and type this way.
62 // A correct type for map-based implementation if we want to go that route
63 // would be `Partial<Record<SentryRequestType, Partial<Record<Outcome, number>>>>`
64 var key = requestTypeToCategory(category) + ":" + reason;
65 flags_1.IS_DEBUG_BUILD && utils_1.logger.log("Adding outcome: " + key);
66 this._outcomes[key] = (_a = this._outcomes[key], (_a !== null && _a !== void 0 ? _a : 0)) + 1;
67 };
68 /**
69 * Send outcomes as an envelope
70 */
71 BaseTransport.prototype._flushOutcomes = function () {
72 if (!this.options.sendClientReports) {
73 return;
74 }
75 var outcomes = this._outcomes;
76 this._outcomes = {};
77 // Nothing to send
78 if (!Object.keys(outcomes).length) {
79 flags_1.IS_DEBUG_BUILD && utils_1.logger.log('No outcomes to flush');
80 return;
81 }
82 flags_1.IS_DEBUG_BUILD && utils_1.logger.log("Flushing outcomes:\n" + JSON.stringify(outcomes, null, 2));
83 var url = core_1.getEnvelopeEndpointWithUrlEncodedAuth(this._api.dsn, this._api.tunnel);
84 var discardedEvents = Object.keys(outcomes).map(function (key) {
85 var _a = tslib_1.__read(key.split(':'), 2), category = _a[0], reason = _a[1];
86 return {
87 reason: reason,
88 category: category,
89 quantity: outcomes[key],
90 };
91 // TODO: Improve types on discarded_events to get rid of cast
92 });
93 var envelope = utils_1.createClientReportEnvelope(discardedEvents, this._api.tunnel && utils_1.dsnToString(this._api.dsn));
94 try {
95 utils_2.sendReport(url, utils_1.serializeEnvelope(envelope));
96 }
97 catch (e) {
98 flags_1.IS_DEBUG_BUILD && utils_1.logger.error(e);
99 }
100 };
101 /**
102 * Handle Sentry repsonse for promise-based transports.
103 */
104 BaseTransport.prototype._handleResponse = function (_a) {
105 var requestType = _a.requestType, response = _a.response, headers = _a.headers, resolve = _a.resolve, reject = _a.reject;
106 var status = utils_1.eventStatusFromHttpCode(response.status);
107 this._rateLimits = utils_1.updateRateLimits(this._rateLimits, headers);
108 // eslint-disable-next-line deprecation/deprecation
109 if (this._isRateLimited(requestType)) {
110 flags_1.IS_DEBUG_BUILD &&
111 // eslint-disable-next-line deprecation/deprecation
112 utils_1.logger.warn("Too many " + requestType + " requests, backing off until: " + this._disabledUntil(requestType));
113 }
114 if (status === 'success') {
115 resolve({ status: status });
116 return;
117 }
118 reject(response);
119 };
120 /**
121 * Gets the time that given category is disabled until for rate limiting
122 *
123 * @deprecated Please use `disabledUntil` from @sentry/utils
124 */
125 BaseTransport.prototype._disabledUntil = function (requestType) {
126 var category = requestTypeToCategory(requestType);
127 return new Date(utils_1.disabledUntil(this._rateLimits, category));
128 };
129 /**
130 * Checks if a category is rate limited
131 *
132 * @deprecated Please use `isRateLimited` from @sentry/utils
133 */
134 BaseTransport.prototype._isRateLimited = function (requestType) {
135 var category = requestTypeToCategory(requestType);
136 return utils_1.isRateLimited(this._rateLimits, category);
137 };
138 return BaseTransport;
139}());
140exports.BaseTransport = BaseTransport;
141//# sourceMappingURL=base.js.map
\No newline at end of file