Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
382 changes: 191 additions & 191 deletions .eslintrc.js

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,40 @@ on:
pull_request:
branches: [ master, staging ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
node: [14, 16, 18, 20, 22, 23]
# mocha 11 requires Node 18.18+, 24 is the active LTS
node: [18, 20, 22, 24]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- run: npm install
- run: npm run build --if-present
- run: npm ci
- run: npm test

deploy:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20.x
- name: Use Node.js 24.x
uses: actions/setup-node@v4
with:
node-version: 20.x
node-version: 24.x
cache: 'npm'
- run: npm install
- run: npm ci
- name: Deploy documentation
shell: bash
env:
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## Next Release
- Fixed a bug where calling "track_errors" repeatedly would register duplicate error handlers, causing a single error to be recorded multiple times
- Fixed a bug in CountlyBulk where explicitly provided "hour", "dow" and "tz" values of 0 were overridden with current time values in "add_request" and "add_bulk_request"
- SDK now removes its process and cluster event listeners when "halt" is called

## 24.10.4
- Added a new init time flag `salt` for request tampering protection (should be used in tandem with server options)

Expand Down
4 changes: 0 additions & 4 deletions bulk_data/.gitignore

This file was deleted.

4 changes: 0 additions & 4 deletions data/.gitignore

This file was deleted.

12 changes: 6 additions & 6 deletions lib/countly-bulk.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ function CountlyBulk(conf) {
query.sdk_version = SDK_VERSION;
query.timestamp = query.timestamp || getMsTimestamp();
var date = new Date((`${query.timestamp}`).length === 13 ? query.timestamp : parseInt(query.timestamp) * 1000);
query.hour = query.hour || date.getHours();
query.dow = query.dow || date.getDay();
query.tz = query.tz || -date.getTimezoneOffset();
query.hour = typeof query.hour !== "undefined" ? query.hour : date.getHours();
query.dow = typeof query.dow !== "undefined" ? query.dow : date.getDay();
query.tz = typeof query.tz !== "undefined" ? query.tz : -date.getTimezoneOffset();

requestQueue.push(query);
cc.log(cc.logLevelEnums.INFO, "CountlyBulk add_request, Adding request to the queue.");
Expand Down Expand Up @@ -196,9 +196,9 @@ function CountlyBulk(conf) {
query.sdk_version = SDK_VERSION;
query.timestamp = query.timestamp || getMsTimestamp();
var date = new Date((`${query.timestamp}`).length === 13 ? query.timestamp : parseInt(query.timestamp) * 1000);
query.hour = query.hour || date.getHours();
query.dow = query.dow || date.getDay();
query.tz = query.tz || -date.getTimezoneOffset();
query.hour = typeof query.hour !== "undefined" ? query.hour : date.getHours();
query.dow = typeof query.dow !== "undefined" ? query.dow : date.getDay();
query.tz = typeof query.tz !== "undefined" ? query.tz : -date.getTimezoneOffset();
cc.log(cc.logLevelEnums.INFO, `CountlyBulk add_bulk_request, adding the request into queue: [${JSON.stringify(query)}]`);
requestQueue.push(query);
}
Expand Down
37 changes: 31 additions & 6 deletions lib/countly.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ Countly.Bulk = Bulk;
var maxStackTraceLineLength = 200;
var deviceIdType = null;
var heartBeatTimer = null;
var uncaughtExceptionHandler = null;
var unhandledRejectionHandler = null;
var clusterForkHandler = null;
/**
* Array with list of available features that you can require consent for
*/
Expand Down Expand Up @@ -275,9 +278,10 @@ Countly.Bulk = Bulk;
}
}
// handle future workers
cluster.on("fork", (worker) => {
clusterForkHandler = (worker) => {
worker.on("message", handleWorkerMessage);
});
};
cluster.on("fork", clusterForkHandler);
if (Countly.remote_config) {
Countly.fetch_remote_config(Countly.remote_config);
}
Expand Down Expand Up @@ -331,6 +335,18 @@ Countly.Bulk = Bulk;
clearInterval(heartBeatTimer);
heartBeatTimer = null;
}
if (clusterForkHandler) {
cluster.removeListener("fork", clusterForkHandler);
clusterForkHandler = null;
}
if (uncaughtExceptionHandler) {
process.removeListener("uncaughtException", uncaughtExceptionHandler);
uncaughtExceptionHandler = null;
}
if (unhandledRejectionHandler) {
process.removeListener("unhandledRejection", unhandledRejectionHandler);
unhandledRejectionHandler = null;
}

// cc DEBUG
cc.debug = false;
Expand Down Expand Up @@ -1100,7 +1116,14 @@ Countly.Bulk = Bulk;
cc.log(cc.logLevelEnums.INFO, `track_errors, Tracking errors. Segments provided: [${segments}].`);

crashSegments = segments;
process.on("uncaughtException", (err) => {
// replace previously registered handlers so repeated calls don't record the same error multiple times
if (uncaughtExceptionHandler) {
process.removeListener("uncaughtException", uncaughtExceptionHandler);
}
if (unhandledRejectionHandler) {
process.removeListener("unhandledRejection", unhandledRejectionHandler);
}
uncaughtExceptionHandler = (err) => {
recordError(err, false);
if (cluster.isMaster) {
CountlyStorage.forceStore();
Expand All @@ -1110,9 +1133,10 @@ Countly.Bulk = Bulk;
// eslint-disable-next-line no-console
console.error(err.stack);
process.exit(1);
});
};
process.on("uncaughtException", uncaughtExceptionHandler);

process.on('unhandledRejection', (reason) => {
unhandledRejectionHandler = (reason) => {
var err = new Error(`Unhandled rejection (reason: ${reason && reason.stack ? reason.stack : reason}).`);
recordError(err, false);
if (cluster.isMaster) {
Expand All @@ -1122,7 +1146,8 @@ Countly.Bulk = Bulk;
console.error(`${(new Date()).toUTCString()} unhandledRejection:`, err.message);
// eslint-disable-next-line no-console
console.error(err.stack);
});
};
process.on('unhandledRejection', unhandledRejectionHandler);
};

/**
Expand Down
Loading
Loading