|
19 | 19 | crashReportingEnabled = false,
|
20 | 20 | captureUnhandledRejections;
|
21 | 21 |
|
| 22 | + var hasSessionStorage = false; |
| 23 | + try { |
| 24 | + hasSessionStorage = !!window.sessionStorage; |
| 25 | + } catch (e) { |
| 26 | + // sessionStorage not available |
| 27 | + } |
| 28 | + |
22 | 29 | var metadata = {
|
23 | 30 | ping : {
|
| 31 | + sessionStorageItem : 'raygun4js-successful-ping', |
24 | 32 | sendPing : true,
|
25 |
| - pingIntervalId : -1, |
26 | 33 | failedPings : 0
|
27 | 34 | },
|
28 | 35 | };
|
|
230 | 237 | };
|
231 | 238 |
|
232 | 239 | function ping() {
|
233 |
| - if(metadata.ping.failedPings > 2) { |
234 |
| - clearInterval(metadata.ping.pingIntervalId); |
235 |
| - } |
236 |
| - |
237 | 240 | if(!Raygun.Options || !Raygun.Options._raygunApiKey || !Raygun.Options._raygunApiUrl){
|
238 |
| - metadata.ping.failedPings++; |
239 |
| - return; |
| 241 | + return; |
240 | 242 | }
|
241 | 243 |
|
242 | 244 | var url = Raygun.Options._raygunApiUrl + "/ping?apiKey=" + encodeURIComponent(Raygun.Options._raygunApiKey);
|
243 | 245 | var data = {
|
244 |
| - crashReportingEnabled: crashReportingEnabled ? true : false, |
245 |
| - realUserMonitoringEnabled: realUserMonitoringEnabled ? true : false, |
246 |
| - providerName: "raygun4js", |
247 |
| - providerVersion: '{{VERSION}}' |
| 246 | + crashReportingEnabled: crashReportingEnabled ? true : false, |
| 247 | + realUserMonitoringEnabled: realUserMonitoringEnabled ? true : false, |
| 248 | + providerName: "raygun4js", |
| 249 | + providerVersion: '{{VERSION}}' |
248 | 250 | };
|
249 | 251 |
|
| 252 | + // Check if we've already pinged with the same data |
| 253 | + if (hasSessionStorage) { |
| 254 | + var storedData = sessionStorage.getItem(metadata.ping.sessionStorageItem); |
| 255 | + if (storedData && storedData === JSON.stringify(data)) { |
| 256 | + return; |
| 257 | + } |
| 258 | + } |
| 259 | + |
250 | 260 | fetch(url, {
|
251 |
| - method: 'POST', |
252 |
| - headers: { |
253 |
| - 'Content-Type': 'application/json' |
254 |
| - }, |
255 |
| - body: JSON.stringify(data) |
| 261 | + method: 'POST', |
| 262 | + headers: { |
| 263 | + 'Content-Type': 'application/json' |
| 264 | + }, |
| 265 | + body: JSON.stringify(data) |
256 | 266 | }).then(function(response) {
|
257 |
| - if (response.ok) { |
258 |
| - metadata.ping.failedPings = 0; |
259 |
| - } else { |
260 |
| - // Request failed |
261 |
| - metadata.ping.failedPings++; |
| 267 | + if (response.ok) { |
| 268 | + if (hasSessionStorage) { |
| 269 | + // Record successful ping in local storage |
| 270 | + sessionStorage.setItem(metadata.ping.sessionStorageItem, JSON.stringify(data)); |
262 | 271 | }
|
263 |
| - }).catch(function() { |
| 272 | + metadata.ping.failedPings = 0; |
| 273 | + } else { |
| 274 | + retryPing(metadata.ping.failedPings); |
264 | 275 | metadata.ping.failedPings++;
|
| 276 | + } |
| 277 | + }).catch(function() { |
| 278 | + retryPing(metadata.ping.failedPings); |
| 279 | + metadata.ping.failedPings++; |
265 | 280 | });
|
266 | 281 | }
|
267 | 282 |
|
| 283 | + var retryPing = function(failedPings) { |
| 284 | + if (failedPings > 5) { |
| 285 | + // Stop retrying after 5 failed attempts |
| 286 | + return; |
| 287 | + } |
| 288 | + |
| 289 | + // Generates a delay of 10/20/40/80/120 seconds |
| 290 | + var backoffDelay = Math.min( |
| 291 | + 10 * Math.pow(2, metadata.ping.failedPings), |
| 292 | + 120 // 2 minutes |
| 293 | + ) * 1000; |
| 294 | + |
| 295 | + // Retry after backoff delay |
| 296 | + setTimeout(ping, backoffDelay); |
| 297 | + }; |
268 | 298 |
|
269 | 299 | var installGlobalExecutor = function() {
|
270 | 300 | window[window['RaygunObject']] = function() {
|
|
325 | 355 |
|
326 | 356 | if(metadata.ping.sendPing) {
|
327 | 357 | ping(); //call immediately
|
328 |
| - metadata.ping.pingIntervalId = setInterval(ping, 1000 * 60 * 5); //5 minutes |
329 | 358 | }
|
330 | 359 | window[window['RaygunObject']].q = errorQueue;
|
331 | 360 | };
|
|
0 commit comments