From 3e921b8eabf9300561eff2c2851c5b7d4b0ecf6a Mon Sep 17 00:00:00 2001 From: turtledreams <62231246+turtledreams@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:17:57 +0900 Subject: [PATCH] [fix] track errors --- .gitignore | 1 + CHANGELOG.md | 4 ++++ cypress/e2e/async_queue.cy.js | 45 +++-------------------------------- cypress/e2e/utm.cy.js | 1 + modules/CountlyClass.js | 13 ++++++---- 5 files changed, 18 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index 23f329c..f1acec4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/ dist/ rollup.config.js +Countly.d.ts ``` \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d2627d..d00506b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 23.12.6 + +* Mitigated an issue where error tracking could prevent SDK initialization in async mode + ## 23.12.5 * Mitigated an issue where the SDK was not emptying the async queue explicity when closing a browser diff --git a/cypress/e2e/async_queue.cy.js b/cypress/e2e/async_queue.cy.js index 0ceb60c..818ec59 100644 --- a/cypress/e2e/async_queue.cy.js +++ b/cypress/e2e/async_queue.cy.js @@ -40,16 +40,17 @@ describe("Test Countly.q related methods and processes", () => { expect(Countly.q.length).to.equal(0); // Add 4 events to the .q + Countly.q.push(['track_errors']); // adding this as calling it during init used to cause an error (at v23.12.5) Countly.q.push(['add_event', event(1)]); Countly.q.push(['add_event', event(2)]); Countly.q.push(['add_event', event(3)]); Countly.q.push(['add_event', event(4)]); // Check that the .q has 4 events - expect(Countly.q.length).to.equal(4); + expect(Countly.q.length).to.equal(5); cy.fetch_local_event_queue().then((rq) => { // Check that events are still in .q - expect(Countly.q.length).to.equal(4); + expect(Countly.q.length).to.equal(5); // Check that the event queue is empty expect(rq.length).to.equal(0); @@ -138,46 +139,6 @@ describe("Test Countly.q related methods and processes", () => { }); }); }); - // This test checks if clear_stored_id set to true during init we call processAsyncQueue (it sends events from .q to event queue and then to request queue) - it('Check clear_stored_id set to true empties the .q', () => { - hp.haltAndClearStorage(() => { - // Disable heartbeat - Countly.noHeartBeat = true; - Countly.q = []; - localStorage.setItem("YOUR_APP_KEY/cly_id", "old_user_id"); // Set old device ID for clear_stored_id to work - - // Add 4 events to the .q - Countly.q.push(['add_event', event(1)]); - Countly.q.push(['add_event', event(2)]); - Countly.q.push(['add_event', event(3)]); - Countly.q.push(['add_event', event(4)]); - - // Check that the .q has 4 events - expect(Countly.q.length).to.equal(4); - - // Init the SDK with clear_stored_id set to true - initMain(true); - cy.wait(1000); - - // Check that the .q is empty - expect(Countly.q.length).to.equal(0); - - cy.fetch_local_event_queue().then((rq) => { - // Check that the event queue is empty because processAsyncQueue sends events from .q to event queue and then to request queue - expect(rq.length).to.equal(0); - - cy.fetch_local_request_queue().then((rq) => { - // Check that events are now in request queue - expect(rq.length).to.equal(1); - const eventsArray = JSON.parse(rq[0].events); - expect(eventsArray[0].key).to.equal("event_1"); - expect(eventsArray[1].key).to.equal("event_2"); - expect(eventsArray[2].key).to.equal("event_3"); - expect(eventsArray[3].key).to.equal("event_4"); - }); - }); - }); - }); // This test checks if calling user_details triggers processAsyncQueue (it sends events from .q to event queue and then to request queue) it('Check sending user details empties .q', () => { hp.haltAndClearStorage(() => { diff --git a/cypress/e2e/utm.cy.js b/cypress/e2e/utm.cy.js index 21c97d2..3a21175 100644 --- a/cypress/e2e/utm.cy.js +++ b/cypress/e2e/utm.cy.js @@ -19,6 +19,7 @@ describe("UTM tests ", () => { it("Checks if a single default utm tag works", () => { hp.haltAndClearStorage(() => { initMulti("YOUR_APP_KEY", "?utm_source=hehe", undefined); + Countly.q.push(['track_errors']); // adding this as calling it during init used to cause an error (at v23.12.5) cy.fetch_local_request_queue().then((rq) => { cy.log(rq); const custom = JSON.parse(rq[0].user_details).custom; diff --git a/modules/CountlyClass.js b/modules/CountlyClass.js index 64bf65c..15de017 100644 --- a/modules/CountlyClass.js +++ b/modules/CountlyClass.js @@ -191,8 +191,7 @@ class CountlyClass { log(logLevelEnums.DEBUG, "initialize, No device ID type info from the previous session, falling back to DEVELOPER_SUPPLIED, for event flushing"); deviceIdType = DeviceIdTypeInternalEnums.DEVELOPER_SUPPLIED; } - // process async queue before sending events - processAsyncQueue(); + // don't process async queue here, just send the events (most likely async data is for the new user) sendEventsForced(); // set them back to their initial values this.device_id = undefined; @@ -393,8 +392,6 @@ class CountlyClass { log(logLevelEnums.DEBUG, "initialize, session_cookie_timeout set to:[" + sessionCookieTimeout + "] minutes to expire a cookies session"); } - log(logLevelEnums.INFO, "initialize, Countly initialized"); - var deviceIdParamValue = null; var searchQuery = self.getSearchQuery(); var hasUTM = false; @@ -528,6 +525,7 @@ class CountlyClass { } // send instant health check request HealthCheck.sendInstantHCRequest(); + log(logLevelEnums.INFO, "initialize, Countly initialized"); }; /** @@ -3778,6 +3776,11 @@ class CountlyClass { * @memberof Countly._internals */ function processAsyncQueue() { + if (typeof Countly === "undefined" || typeof Countly.i === "undefined") { + log(logLevelEnums.DEBUG, "Countly is not finished initialization yet, will process the queue after initialization is done"); + return; + } + const q = Countly.q; Countly.q = []; for (let i = 0; i < q.length; i++) { @@ -3798,6 +3801,8 @@ class CountlyClass { } catch (error) { // possibly first init and no other instance log(logLevelEnums.DEBUG, "No instance found for the provided key while processing async queue"); + Countly.q.push(req); // return it back to queue and continue to the next one + continue; } if (typeof inst[req[arg]] === "function") { inst[req[arg]].apply(inst, req.slice(arg + 1));