rollbar 2.26.2 → 2.26.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +32 -10
- package/.lgtm.yml +7 -7
- package/.prettierignore +18 -0
- package/.vscode/settings.json +39 -0
- package/CHANGELOG.md +121 -35
- package/Gruntfile.js +51 -71
- package/README.md +2 -4
- package/bower.json +1 -3
- package/defaults.js +17 -5
- package/dist/plugins/jquery.min.js +1 -1
- package/dist/rollbar.js +5699 -5052
- package/dist/rollbar.js.map +1 -1
- package/dist/rollbar.min.js +1 -1
- package/dist/rollbar.min.js.map +1 -1
- package/dist/rollbar.named-amd.js +5704 -5062
- package/dist/rollbar.named-amd.js.map +1 -1
- package/dist/rollbar.named-amd.min.js +1 -1
- package/dist/rollbar.named-amd.min.js.map +1 -1
- package/dist/rollbar.noconflict.umd.js +5693 -5052
- package/dist/rollbar.noconflict.umd.js.map +1 -1
- package/dist/rollbar.noconflict.umd.min.js +1 -1
- package/dist/rollbar.noconflict.umd.min.js.map +1 -1
- package/dist/rollbar.snippet.js +1 -1
- package/dist/rollbar.umd.js +5704 -5063
- package/dist/rollbar.umd.js.map +1 -1
- package/dist/rollbar.umd.min.js +1 -1
- package/dist/rollbar.umd.min.js.map +1 -1
- package/docs/extension-exceptions.md +35 -30
- package/docs/migration_v0_to_v1.md +41 -38
- package/index.d.ts +270 -231
- package/karma.conf.js +16 -34
- package/package.json +21 -17
- package/prettier.config.js +7 -0
- package/src/api.js +21 -10
- package/src/apiUtility.js +12 -8
- package/src/browser/core.js +103 -65
- package/src/browser/defaults/scrubFields.js +3 -3
- package/src/browser/detection.js +7 -8
- package/src/browser/domUtility.js +18 -8
- package/src/browser/globalSetup.js +12 -6
- package/src/browser/logger.js +1 -1
- package/src/browser/plugins/jquery.js +35 -35
- package/src/browser/predicates.js +1 -1
- package/src/browser/rollbar.js +1 -1
- package/src/browser/rollbarWrapper.js +8 -5
- package/src/browser/shim.js +43 -19
- package/src/browser/snippet_callback.js +6 -4
- package/src/browser/telemetry.js +573 -354
- package/src/browser/transforms.js +46 -27
- package/src/browser/transport/fetch.js +16 -14
- package/src/browser/transport/xhr.js +29 -13
- package/src/browser/transport.js +82 -25
- package/src/browser/url.js +16 -8
- package/src/browser/wrapGlobals.js +27 -8
- package/src/defaults.js +3 -3
- package/src/errorParser.js +14 -11
- package/src/merge.js +32 -23
- package/src/notifier.js +16 -13
- package/src/predicates.js +43 -23
- package/src/queue.js +71 -39
- package/src/rateLimiter.js +59 -18
- package/src/react-native/logger.js +1 -1
- package/src/react-native/rollbar.js +59 -55
- package/src/react-native/transforms.js +13 -9
- package/src/react-native/transport.js +44 -34
- package/src/rollbar.js +22 -13
- package/src/scrub.js +0 -1
- package/src/server/locals.js +69 -39
- package/src/server/logger.js +4 -4
- package/src/server/parser.js +72 -47
- package/src/server/rollbar.js +133 -55
- package/src/server/sourceMap/stackTrace.js +33 -18
- package/src/server/telemetry/urlHelpers.js +9 -11
- package/src/server/telemetry.js +68 -45
- package/src/server/transforms.js +37 -21
- package/src/server/transport.js +62 -32
- package/src/telemetry.js +92 -28
- package/src/transforms.js +33 -21
- package/src/truncation.js +8 -5
- package/src/utility/headers.js +43 -43
- package/src/utility/replace.js +9 -0
- package/src/utility/traverse.js +1 -1
- package/src/utility.js +89 -52
- package/test/api.test.js +31 -29
- package/test/apiUtility.test.js +43 -44
- package/test/browser.core.test.js +141 -131
- package/test/browser.domUtility.test.js +52 -35
- package/test/browser.predicates.test.js +13 -13
- package/test/browser.rollbar.test.js +597 -503
- package/test/browser.telemetry.test.js +76 -0
- package/test/browser.transforms.test.js +146 -128
- package/test/browser.transport.test.js +54 -46
- package/test/browser.url.test.js +12 -11
- package/test/fixtures/locals.fixtures.js +245 -126
- package/test/notifier.test.js +90 -78
- package/test/predicates.test.js +260 -214
- package/test/queue.test.js +230 -214
- package/test/rateLimiter.test.js +50 -42
- package/test/react-native.rollbar.test.js +149 -115
- package/test/react-native.transforms.test.js +21 -23
- package/test/react-native.transport.test.js +23 -11
- package/test/server.lambda.test.js +70 -53
- package/test/server.locals.test.js +437 -210
- package/test/server.parser.test.js +32 -26
- package/test/server.predicates.test.js +45 -43
- package/test/server.rollbar.test.js +311 -259
- package/test/server.telemetry.test.js +208 -83
- package/test/server.transforms.test.js +455 -361
- package/test/server.transport.test.js +144 -76
- package/test/telemetry.test.js +46 -37
- package/test/transforms.test.js +68 -66
- package/test/truncation.test.js +55 -53
- package/test/utility.test.js +266 -222
- package/webpack.config.js +46 -43
- package/.gitmodules +0 -3
- package/browserstack.browsers.js +0 -153
- package/browserstack.browsers.json +0 -4384
package/src/server/telemetry.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
var http = require('http');
|
|
2
2
|
var https = require('https');
|
|
3
3
|
var _ = require('../utility');
|
|
4
|
+
var replace = require('../utility/replace');
|
|
4
5
|
var urlHelpers = require('./telemetry/urlHelpers');
|
|
5
6
|
|
|
6
7
|
var defaults = {
|
|
7
8
|
network: true,
|
|
8
9
|
networkResponseHeaders: false,
|
|
9
10
|
networkRequestHeaders: false,
|
|
10
|
-
log: true
|
|
11
|
+
log: true,
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
function Instrumenter(options, telemeter, rollbar) {
|
|
@@ -26,11 +27,11 @@ function Instrumenter(options, telemeter, rollbar) {
|
|
|
26
27
|
this.diagnostic = rollbar.client.notifier.diagnostic;
|
|
27
28
|
this.replacements = {
|
|
28
29
|
network: [],
|
|
29
|
-
log: []
|
|
30
|
+
log: [],
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
Instrumenter.prototype.configure = function(options) {
|
|
34
|
+
Instrumenter.prototype.configure = function (options) {
|
|
34
35
|
this.options = _.merge(this.options, options);
|
|
35
36
|
var autoInstrument = options.autoInstrument;
|
|
36
37
|
var oldSettings = _.merge(this.autoInstrument);
|
|
@@ -45,10 +46,14 @@ Instrumenter.prototype.configure = function(options) {
|
|
|
45
46
|
this.instrument(oldSettings);
|
|
46
47
|
};
|
|
47
48
|
|
|
48
|
-
Instrumenter.prototype.instrument = function(oldSettings) {
|
|
49
|
+
Instrumenter.prototype.instrument = function (oldSettings) {
|
|
49
50
|
if (this.autoInstrument.network && !(oldSettings && oldSettings.network)) {
|
|
50
51
|
this.instrumentNetwork();
|
|
51
|
-
} else if (
|
|
52
|
+
} else if (
|
|
53
|
+
!this.autoInstrument.network &&
|
|
54
|
+
oldSettings &&
|
|
55
|
+
oldSettings.network
|
|
56
|
+
) {
|
|
52
57
|
this.deinstrumentNetwork();
|
|
53
58
|
}
|
|
54
59
|
|
|
@@ -59,20 +64,32 @@ Instrumenter.prototype.instrument = function(oldSettings) {
|
|
|
59
64
|
}
|
|
60
65
|
};
|
|
61
66
|
|
|
62
|
-
Instrumenter.prototype.deinstrumentNetwork = function() {
|
|
67
|
+
Instrumenter.prototype.deinstrumentNetwork = function () {
|
|
63
68
|
restore(this.replacements, 'network');
|
|
64
69
|
};
|
|
65
70
|
|
|
66
|
-
Instrumenter.prototype.instrumentNetwork = function() {
|
|
67
|
-
replace(
|
|
68
|
-
|
|
71
|
+
Instrumenter.prototype.instrumentNetwork = function () {
|
|
72
|
+
replace(
|
|
73
|
+
http,
|
|
74
|
+
'request',
|
|
75
|
+
networkRequestWrapper.bind(this),
|
|
76
|
+
this.replacements,
|
|
77
|
+
'network',
|
|
78
|
+
);
|
|
79
|
+
replace(
|
|
80
|
+
https,
|
|
81
|
+
'request',
|
|
82
|
+
networkRequestWrapper.bind(this),
|
|
83
|
+
this.replacements,
|
|
84
|
+
'network',
|
|
85
|
+
);
|
|
69
86
|
};
|
|
70
87
|
|
|
71
88
|
function networkRequestWrapper(orig) {
|
|
72
89
|
var telemeter = this.telemeter;
|
|
73
90
|
var self = this;
|
|
74
91
|
|
|
75
|
-
return function(url, options, cb) {
|
|
92
|
+
return function (url, options, cb) {
|
|
76
93
|
var mergedOptions = urlHelpers.mergeOptions(url, options, cb);
|
|
77
94
|
|
|
78
95
|
var metadata = {
|
|
@@ -80,7 +97,7 @@ function networkRequestWrapper(orig) {
|
|
|
80
97
|
url: urlHelpers.constructUrl(mergedOptions.options),
|
|
81
98
|
status_code: null,
|
|
82
99
|
start_time_ms: _.now(),
|
|
83
|
-
end_time_ms: null
|
|
100
|
+
end_time_ms: null,
|
|
84
101
|
};
|
|
85
102
|
|
|
86
103
|
if (self.autoInstrument.networkRequestHeaders) {
|
|
@@ -90,20 +107,24 @@ function networkRequestWrapper(orig) {
|
|
|
90
107
|
|
|
91
108
|
// Call the original method with the original arguments and wrapped callback.
|
|
92
109
|
var wrappedArgs = Array.from(arguments);
|
|
93
|
-
var wrappedCallback = responseCallbackWrapper(
|
|
110
|
+
var wrappedCallback = responseCallbackWrapper(
|
|
111
|
+
self.autoInstrument,
|
|
112
|
+
metadata,
|
|
113
|
+
mergedOptions.cb,
|
|
114
|
+
);
|
|
94
115
|
if (mergedOptions.cb) {
|
|
95
116
|
wrappedArgs.pop();
|
|
96
117
|
}
|
|
97
118
|
wrappedArgs.push(wrappedCallback);
|
|
98
119
|
var req = orig.apply(https, wrappedArgs);
|
|
99
120
|
|
|
100
|
-
req.on('error', err => {
|
|
121
|
+
req.on('error', (err) => {
|
|
101
122
|
metadata.status_code = 0;
|
|
102
|
-
metadata.error = [err.name, err.message].join(': ')
|
|
123
|
+
metadata.error = [err.name, err.message].join(': ');
|
|
103
124
|
});
|
|
104
125
|
|
|
105
126
|
return req;
|
|
106
|
-
}
|
|
127
|
+
};
|
|
107
128
|
}
|
|
108
129
|
|
|
109
130
|
function responseCallbackWrapper(options, metadata, callback) {
|
|
@@ -118,51 +139,53 @@ function responseCallbackWrapper(options, metadata, callback) {
|
|
|
118
139
|
if (callback) {
|
|
119
140
|
return callback.apply(undefined, arguments);
|
|
120
141
|
}
|
|
121
|
-
}
|
|
142
|
+
};
|
|
122
143
|
}
|
|
123
144
|
|
|
124
|
-
Instrumenter.prototype.captureNetwork = function(
|
|
145
|
+
Instrumenter.prototype.captureNetwork = function (
|
|
146
|
+
metadata,
|
|
147
|
+
subtype,
|
|
148
|
+
rollbarUUID,
|
|
149
|
+
) {
|
|
125
150
|
return this.telemeter.captureNetwork(metadata, subtype, rollbarUUID);
|
|
126
151
|
};
|
|
127
152
|
|
|
128
|
-
Instrumenter.prototype.deinstrumentConsole = function() {
|
|
153
|
+
Instrumenter.prototype.deinstrumentConsole = function () {
|
|
129
154
|
restore(this.replacements, 'log');
|
|
130
155
|
};
|
|
131
156
|
|
|
132
|
-
Instrumenter.prototype.instrumentConsole = function() {
|
|
157
|
+
Instrumenter.prototype.instrumentConsole = function () {
|
|
133
158
|
var telemeter = this.telemeter;
|
|
134
159
|
|
|
135
160
|
var stdout = process.stdout;
|
|
136
|
-
replace(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
161
|
+
replace(
|
|
162
|
+
stdout,
|
|
163
|
+
'write',
|
|
164
|
+
function (orig) {
|
|
165
|
+
return function (string) {
|
|
166
|
+
telemeter.captureLog(string, 'info');
|
|
167
|
+
return orig.apply(stdout, arguments);
|
|
168
|
+
};
|
|
169
|
+
},
|
|
170
|
+
this.replacements,
|
|
171
|
+
'log',
|
|
172
|
+
);
|
|
142
173
|
|
|
143
174
|
var stderr = process.stderr;
|
|
144
|
-
replace(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
175
|
+
replace(
|
|
176
|
+
stderr,
|
|
177
|
+
'write',
|
|
178
|
+
function (orig) {
|
|
179
|
+
return function (string) {
|
|
180
|
+
telemeter.captureLog(string, 'error');
|
|
181
|
+
return orig.apply(stderr, arguments);
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
this.replacements,
|
|
185
|
+
'log',
|
|
186
|
+
);
|
|
150
187
|
};
|
|
151
188
|
|
|
152
|
-
// TODO: These helpers are duplicated in src/browser/telemetry.js,
|
|
153
|
-
// and may be candidates for extraction into a shared module.
|
|
154
|
-
// It is recommended that before doing so, the author should allow
|
|
155
|
-
// for more telemetry types to be implemented for the Node target
|
|
156
|
-
// to ensure that the implementations of these helpers don't diverge.
|
|
157
|
-
// If they do diverge, there's little point in the shared module.
|
|
158
|
-
function replace(obj, name, replacement, replacements, type) {
|
|
159
|
-
var orig = obj[name];
|
|
160
|
-
obj[name] = replacement(orig);
|
|
161
|
-
if (replacements) {
|
|
162
|
-
replacements[type].push([obj, name, orig]);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
189
|
function restore(replacements, type) {
|
|
167
190
|
var b;
|
|
168
191
|
while (replacements[type].length) {
|
package/src/server/transforms.js
CHANGED
|
@@ -6,7 +6,8 @@ var _ = require('../utility');
|
|
|
6
6
|
var scrub = require('../scrub');
|
|
7
7
|
|
|
8
8
|
function baseData(item, options, callback) {
|
|
9
|
-
var environment =
|
|
9
|
+
var environment =
|
|
10
|
+
(options.payload && options.payload.environment) || options.environment;
|
|
10
11
|
var data = {
|
|
11
12
|
timestamp: Math.round(item.timestamp / 1000),
|
|
12
13
|
environment: item.environment || environment,
|
|
@@ -15,7 +16,7 @@ function baseData(item, options, callback) {
|
|
|
15
16
|
framework: item.framework || options.framework,
|
|
16
17
|
uuid: item.uuid,
|
|
17
18
|
notifier: JSON.parse(JSON.stringify(options.notifier)),
|
|
18
|
-
custom: item.custom
|
|
19
|
+
custom: item.custom,
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
if (options.codeVersion) {
|
|
@@ -34,7 +35,7 @@ function baseData(item, options, callback) {
|
|
|
34
35
|
data.server = {
|
|
35
36
|
host: options.host,
|
|
36
37
|
argv: process.argv.concat(),
|
|
37
|
-
pid: process.pid
|
|
38
|
+
pid: process.pid,
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
if (options.branch) {
|
|
@@ -53,7 +54,7 @@ function addMessageData(item, options, callback) {
|
|
|
53
54
|
item.data.body = item.data.body || {};
|
|
54
55
|
var message = item.message || 'Item sent with null or missing arguments.';
|
|
55
56
|
item.data.body.message = {
|
|
56
|
-
body: message
|
|
57
|
+
body: message,
|
|
57
58
|
};
|
|
58
59
|
callback(null, item);
|
|
59
60
|
}
|
|
@@ -93,9 +94,13 @@ function handleItemWithError(item, options, callback) {
|
|
|
93
94
|
_.addErrorContext(item, errors);
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
var cb = function(e) {
|
|
97
|
+
var cb = function (e) {
|
|
97
98
|
if (e) {
|
|
98
|
-
item.message =
|
|
99
|
+
item.message =
|
|
100
|
+
item.err.message ||
|
|
101
|
+
item.err.description ||
|
|
102
|
+
item.message ||
|
|
103
|
+
String(item.err);
|
|
99
104
|
item.diagnostic.buildTraceData = e.message;
|
|
100
105
|
delete item.stackInfo;
|
|
101
106
|
}
|
|
@@ -129,11 +134,13 @@ function addRequestData(item, options, callback) {
|
|
|
129
134
|
|
|
130
135
|
if (req.route) {
|
|
131
136
|
routePath = req.route.path;
|
|
132
|
-
item.data.context =
|
|
137
|
+
item.data.context =
|
|
138
|
+
baseUrl && baseUrl.length ? baseUrl + routePath : routePath;
|
|
133
139
|
} else {
|
|
134
140
|
try {
|
|
135
141
|
routePath = req.app._router.matchRequest(req).path;
|
|
136
|
-
item.data.context =
|
|
142
|
+
item.data.context =
|
|
143
|
+
baseUrl && baseUrl.length ? baseUrl + routePath : routePath;
|
|
137
144
|
} catch (ignore) {
|
|
138
145
|
// Ignored
|
|
139
146
|
}
|
|
@@ -151,7 +158,7 @@ function addRequestData(item, options, callback) {
|
|
|
151
158
|
}
|
|
152
159
|
item.data.person = person;
|
|
153
160
|
} else if (req.user) {
|
|
154
|
-
item.data.person = {id: req.user.id};
|
|
161
|
+
item.data.person = { id: req.user.id };
|
|
155
162
|
if (req.user.username && captureUsername) {
|
|
156
163
|
item.data.person.username = req.user.username;
|
|
157
164
|
}
|
|
@@ -163,7 +170,7 @@ function addRequestData(item, options, callback) {
|
|
|
163
170
|
if (_.isFunction(userId)) {
|
|
164
171
|
userId = userId();
|
|
165
172
|
}
|
|
166
|
-
item.data.person = {id: userId};
|
|
173
|
+
item.data.person = { id: userId };
|
|
167
174
|
}
|
|
168
175
|
|
|
169
176
|
callback(null, item);
|
|
@@ -182,7 +189,7 @@ function addLambdaData(item, options, callback) {
|
|
|
182
189
|
functionName: c.functionName,
|
|
183
190
|
functionVersion: c.functionVersion,
|
|
184
191
|
arn: c.invokedFunctionArn,
|
|
185
|
-
requestId: c.awsRequestId
|
|
192
|
+
requestId: c.awsRequestId,
|
|
186
193
|
};
|
|
187
194
|
|
|
188
195
|
item.data = item.data || {};
|
|
@@ -206,7 +213,9 @@ function scrubPayload(item, options, callback) {
|
|
|
206
213
|
}
|
|
207
214
|
|
|
208
215
|
function parseRequestBody(req, options) {
|
|
209
|
-
if (!req || !options.scrubRequestBody) {
|
|
216
|
+
if (!req || !options.scrubRequestBody) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
210
219
|
|
|
211
220
|
try {
|
|
212
221
|
if (_.isString(req.body) && _isJsonContentType(req)) {
|
|
@@ -219,7 +228,9 @@ function parseRequestBody(req, options) {
|
|
|
219
228
|
}
|
|
220
229
|
|
|
221
230
|
function serializeRequestBody(req, options) {
|
|
222
|
-
if (!req || !options.scrubRequestBody) {
|
|
231
|
+
if (!req || !options.scrubRequestBody) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
223
234
|
|
|
224
235
|
try {
|
|
225
236
|
if (_.isObject(req.body) && _isJsonContentType(req)) {
|
|
@@ -234,11 +245,15 @@ function serializeRequestBody(req, options) {
|
|
|
234
245
|
/** Helpers **/
|
|
235
246
|
|
|
236
247
|
function _isJsonContentType(req) {
|
|
237
|
-
return
|
|
248
|
+
return (
|
|
249
|
+
req.headers &&
|
|
250
|
+
req.headers['content-type'] &&
|
|
251
|
+
req.headers['content-type'].includes('json')
|
|
252
|
+
);
|
|
238
253
|
}
|
|
239
254
|
|
|
240
255
|
function _buildTraceData(chain, options, item) {
|
|
241
|
-
return function(ex, cb) {
|
|
256
|
+
return function (ex, cb) {
|
|
242
257
|
parser.parseException(ex, options, item, function (err, errData) {
|
|
243
258
|
if (err) {
|
|
244
259
|
return cb(err);
|
|
@@ -248,8 +263,8 @@ function _buildTraceData(chain, options, item) {
|
|
|
248
263
|
frames: errData.frames,
|
|
249
264
|
exception: {
|
|
250
265
|
class: errData['class'],
|
|
251
|
-
message: errData.message
|
|
252
|
-
}
|
|
266
|
+
message: errData.message,
|
|
267
|
+
},
|
|
253
268
|
});
|
|
254
269
|
|
|
255
270
|
return cb(null);
|
|
@@ -268,11 +283,12 @@ function _extractIp(req) {
|
|
|
268
283
|
function _buildRequestData(req) {
|
|
269
284
|
var headers = req.headers || {};
|
|
270
285
|
var host = headers.host || '<no host>';
|
|
271
|
-
var proto =
|
|
286
|
+
var proto =
|
|
287
|
+
req.protocol || (req.socket && req.socket.encrypted ? 'https' : 'http');
|
|
272
288
|
var parsedUrl;
|
|
273
289
|
var baseUrl = req.baseUrl || '';
|
|
274
290
|
if (_.isType(req.url, 'string')) {
|
|
275
|
-
var fullUrl = baseUrl && baseUrl.length ? baseUrl + req.url : req.url
|
|
291
|
+
var fullUrl = baseUrl && baseUrl.length ? baseUrl + req.url : req.url;
|
|
276
292
|
parsedUrl = url.parse(fullUrl, true);
|
|
277
293
|
} else {
|
|
278
294
|
parsedUrl = req.url || {};
|
|
@@ -284,7 +300,7 @@ function _buildRequestData(req) {
|
|
|
284
300
|
url: reqUrl,
|
|
285
301
|
user_ip: _extractIp(req),
|
|
286
302
|
headers: headers,
|
|
287
|
-
method: req.method
|
|
303
|
+
method: req.method,
|
|
288
304
|
};
|
|
289
305
|
if (parsedUrl.search && parsedUrl.search.length > 0) {
|
|
290
306
|
data.GET = parsedUrl.query;
|
|
@@ -315,5 +331,5 @@ module.exports = {
|
|
|
315
331
|
addErrorData: addErrorData,
|
|
316
332
|
addRequestData: addRequestData,
|
|
317
333
|
addLambdaData: addLambdaData,
|
|
318
|
-
scrubPayload: scrubPayload
|
|
334
|
+
scrubPayload: scrubPayload,
|
|
319
335
|
};
|
package/src/server/transport.js
CHANGED
|
@@ -28,10 +28,16 @@ function Transport() {
|
|
|
28
28
|
this.rateLimitExpires = 0;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
Transport.prototype.get = function(
|
|
31
|
+
Transport.prototype.get = function (
|
|
32
|
+
accessToken,
|
|
33
|
+
options,
|
|
34
|
+
params,
|
|
35
|
+
callback,
|
|
36
|
+
transportFactory,
|
|
37
|
+
) {
|
|
32
38
|
var t;
|
|
33
39
|
if (!callback || !_.isFunction(callback)) {
|
|
34
|
-
callback = function() {};
|
|
40
|
+
callback = function () {};
|
|
35
41
|
}
|
|
36
42
|
options = options || {};
|
|
37
43
|
_.addParamsAndAccessTokenToPath(accessToken, options, params);
|
|
@@ -42,22 +48,33 @@ Transport.prototype.get = function(accessToken, options, params, callback, trans
|
|
|
42
48
|
t = _transport(options);
|
|
43
49
|
}
|
|
44
50
|
if (!t) {
|
|
45
|
-
logger.error(
|
|
51
|
+
logger.error(
|
|
52
|
+
'Unknown transport based on given protocol: ' + options.protocol,
|
|
53
|
+
);
|
|
46
54
|
return callback(new Error('Unknown transport'));
|
|
47
55
|
}
|
|
48
|
-
var req = t.request(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
var req = t.request(
|
|
57
|
+
options,
|
|
58
|
+
function (resp) {
|
|
59
|
+
this.handleResponse(resp, callback);
|
|
60
|
+
}.bind(this),
|
|
61
|
+
);
|
|
62
|
+
req.on('error', function (err) {
|
|
52
63
|
callback(err);
|
|
53
64
|
});
|
|
54
65
|
req.end();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
Transport.prototype.post = function(
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
Transport.prototype.post = function (
|
|
69
|
+
accessToken,
|
|
70
|
+
options,
|
|
71
|
+
payload,
|
|
72
|
+
callback,
|
|
73
|
+
transportFactory,
|
|
74
|
+
) {
|
|
58
75
|
var t;
|
|
59
76
|
if (!callback || !_.isFunction(callback)) {
|
|
60
|
-
callback = function() {};
|
|
77
|
+
callback = function () {};
|
|
61
78
|
}
|
|
62
79
|
if (_currentTime() < this.rateLimitExpires) {
|
|
63
80
|
return callback(new Error('Exceeded rate limit'));
|
|
@@ -79,47 +96,55 @@ Transport.prototype.post = function(accessToken, options, payload, callback, tra
|
|
|
79
96
|
t = _transport(options);
|
|
80
97
|
}
|
|
81
98
|
if (!t) {
|
|
82
|
-
logger.error(
|
|
99
|
+
logger.error(
|
|
100
|
+
'Unknown transport based on given protocol: ' + options.protocol,
|
|
101
|
+
);
|
|
83
102
|
return callback(new Error('Unknown transport'));
|
|
84
103
|
}
|
|
85
|
-
var req = t.request(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
104
|
+
var req = t.request(
|
|
105
|
+
options,
|
|
106
|
+
function (resp) {
|
|
107
|
+
this.handleResponse(resp, _wrapPostCallback(callback));
|
|
108
|
+
}.bind(this),
|
|
109
|
+
);
|
|
110
|
+
req.on('error', function (err) {
|
|
89
111
|
callback(err);
|
|
90
112
|
});
|
|
91
113
|
if (writeData) {
|
|
92
114
|
req.write(writeData);
|
|
93
115
|
}
|
|
94
116
|
req.end();
|
|
95
|
-
}
|
|
117
|
+
};
|
|
96
118
|
|
|
97
|
-
Transport.prototype.updateRateLimit = function(resp) {
|
|
119
|
+
Transport.prototype.updateRateLimit = function (resp) {
|
|
98
120
|
var remaining = parseInt(resp.headers['x-rate-limit-remaining'] || 0);
|
|
99
|
-
var remainingSeconds = Math.min(
|
|
121
|
+
var remainingSeconds = Math.min(
|
|
122
|
+
MAX_RATE_LIMIT_INTERVAL,
|
|
123
|
+
resp.headers['x-rate-limit-remaining-seconds'] || 0,
|
|
124
|
+
);
|
|
100
125
|
var currentTime = _currentTime();
|
|
101
126
|
|
|
102
|
-
if (
|
|
127
|
+
if (resp.statusCode === 429 && remaining === 0) {
|
|
103
128
|
this.rateLimitExpires = currentTime + remainingSeconds;
|
|
104
129
|
} else {
|
|
105
130
|
this.rateLimitExpires = currentTime;
|
|
106
131
|
}
|
|
107
|
-
}
|
|
132
|
+
};
|
|
108
133
|
|
|
109
|
-
Transport.prototype.handleResponse = function(resp, callback) {
|
|
134
|
+
Transport.prototype.handleResponse = function (resp, callback) {
|
|
110
135
|
this.updateRateLimit(resp);
|
|
111
136
|
|
|
112
137
|
var respData = [];
|
|
113
138
|
resp.setEncoding('utf8');
|
|
114
|
-
resp.on('data', function(chunk) {
|
|
139
|
+
resp.on('data', function (chunk) {
|
|
115
140
|
respData.push(chunk);
|
|
116
141
|
});
|
|
117
142
|
|
|
118
|
-
resp.on('end', function() {
|
|
143
|
+
resp.on('end', function () {
|
|
119
144
|
respData = respData.join('');
|
|
120
145
|
_parseApiResponse(respData, callback);
|
|
121
146
|
});
|
|
122
|
-
}
|
|
147
|
+
};
|
|
123
148
|
|
|
124
149
|
/** Helpers **/
|
|
125
150
|
|
|
@@ -138,7 +163,7 @@ function _headers(accessToken, options, data) {
|
|
|
138
163
|
}
|
|
139
164
|
|
|
140
165
|
function _transport(options) {
|
|
141
|
-
return {'http:': http, 'https:': https}[options.protocol];
|
|
166
|
+
return { 'http:': http, 'https:': https }[options.protocol];
|
|
142
167
|
}
|
|
143
168
|
|
|
144
169
|
function _parseApiResponse(data, callback) {
|
|
@@ -151,27 +176,32 @@ function _parseApiResponse(data, callback) {
|
|
|
151
176
|
|
|
152
177
|
if (data.err) {
|
|
153
178
|
logger.error('Received error: ' + data.message);
|
|
154
|
-
return callback(
|
|
179
|
+
return callback(
|
|
180
|
+
new Error('Api error: ' + (data.message || 'Unknown error')),
|
|
181
|
+
);
|
|
155
182
|
}
|
|
156
183
|
|
|
157
184
|
callback(null, data);
|
|
158
185
|
}
|
|
159
186
|
|
|
160
187
|
function _wrapPostCallback(callback) {
|
|
161
|
-
return function(err, data) {
|
|
188
|
+
return function (err, data) {
|
|
162
189
|
if (err) {
|
|
163
190
|
return callback(err);
|
|
164
191
|
}
|
|
165
192
|
if (data.result && data.result.uuid) {
|
|
166
|
-
logger.log(
|
|
193
|
+
logger.log(
|
|
194
|
+
[
|
|
167
195
|
'Successful api response.',
|
|
168
|
-
' Link: https://rollbar.com/occurrence/uuid/?uuid=' +
|
|
169
|
-
|
|
196
|
+
' Link: https://rollbar.com/occurrence/uuid/?uuid=' +
|
|
197
|
+
data.result.uuid,
|
|
198
|
+
].join(''),
|
|
199
|
+
);
|
|
170
200
|
} else {
|
|
171
201
|
logger.log('Successful api response');
|
|
172
202
|
}
|
|
173
203
|
callback(null, data.result);
|
|
174
|
-
}
|
|
204
|
+
};
|
|
175
205
|
}
|
|
176
206
|
|
|
177
207
|
function _currentTime() {
|