Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit b35bd2b

Browse files
bardisgMoumitaMsaikumarrs
authored
fix: bugsnag error reporting (#856)
* fix: fix Bugsnug version detection & error reporting initialization * fix: remove node assert import * refactor: rename folder for error reporting feature * chore: use case handled * chore: fix circular dependency * chore: update size limit * test: error reporting service test suite * test: test suite for bugsnag * chore: updated method signatures for v6 bugsnag * fix: address pr comments * fix: use the latest config key for error reports * fix: remove the default value for error collection * fix: rename config flags in test scripts to fix failures * chore: add more test cases to improve coverage * fix: allow only boolean values for error collection enable flag * refactor: remove redundant code * refactor: remove redundant client check * refactor: fix the typo * fix: update package-lock.json to latest --------- Co-authored-by: Moumita <[email protected]> Co-authored-by: Moumita <[email protected]> Co-authored-by: saikumarrs <[email protected]>
1 parent 66bb84f commit b35bd2b

File tree

19 files changed

+2359
-5214
lines changed

19 files changed

+2359
-5214
lines changed

.github/workflows/deploy-dev.yml

+2-6
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,13 @@ jobs:
3636
- name: Build files
3737
env:
3838
HUSKY: 0
39+
BUGSNAG_API_KEY: ${{ secrets.RS_DEV_BUGSNAG_API_KEY }}
40+
BUGSNAG_RELEASE_STAGE: 'development'
3941
run: |
4042
npm ci
4143
npm run build:browser:dev
4244
npm run build:integration:all
4345
44-
- name: Fix Bugsnag API key
45-
env:
46-
BUGSNAG_API_KEY: ${{ secrets.RS_DEV_BUGSNAG_API_KEY }}
47-
run: |
48-
sed -i -e 's|{{RS_BUGSNAG_API_KEY}}|'$BUGSNAG_API_KEY'|' dist/legacy/rudder-analytics.js
49-
5046
- name: Sync files to S3
5147
run: |
5248
aws s3 cp dist/legacy/rudder-analytics.js s3://${{ secrets.AWS_DEV_S3_BUCKET_NAME }}/dev/latest/rudder-analytics.js --cache-control max-age=3600

.github/workflows/deploy-prod.yml

+2-7
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,15 @@ jobs:
3636
- name: Build and sync files to S3
3737
env:
3838
HUSKY: 0
39+
BUGSNAG_API_KEY: ${{ secrets.RS_PROD_BUGSNAG_API_KEY }}
40+
BUGSNAG_RELEASE_STAGE: 'production'
3941
run: |
4042
npm ci
4143
npm run build:browser
4244
npm run build:browser:modern
4345
npm run build:integration:all
4446
npm run build:integration:all:modern
4547
46-
- name: Fix Bugsnag API key
47-
env:
48-
BUGSNAG_API_KEY: ${{ secrets.RS_PROD_BUGSNAG_API_KEY }}
49-
run: |
50-
sed -i -e 's|{{RS_BUGSNAG_API_KEY}}|'$BUGSNAG_API_KEY'|' dist/legacy/rudder-analytics.min.js
51-
sed -i -e 's|{{RS_BUGSNAG_API_KEY}}|'$BUGSNAG_API_KEY'|' dist/modern/rudder-analytics.min.js
52-
5348
- name: Get new version number
5449
run: |
5550
current_version=$(jq -r .version package.json)

.github/workflows/deploy-staging.yml

+2-6
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,13 @@ jobs:
3131
- name: Build and sync files to S3
3232
env:
3333
HUSKY: 0
34+
BUGSNAG_API_KEY: ${{ secrets.RS_STAGING_BUGSNAG_API_KEY }}
35+
BUGSNAG_RELEASE_STAGE: 'development'
3436
run: |
3537
npm ci
3638
npm run build:browser --staging=true
3739
npm run build:integration:all --staging=true
3840
39-
- name: Fix Bugsnag API key
40-
env:
41-
BUGSNAG_API_KEY: ${{ secrets.RS_STAGING_BUGSNAG_API_KEY }}
42-
run: |
43-
sed -i -e 's|{{RS_BUGSNAG_API_KEY}}|'$BUGSNAG_API_KEY'|' dist/legacy/rudder-analytics-staging.min.js
44-
4541
- name: Get new version number
4642
run: |
4743
current_version=$(jq -r .version package.json)

.size-limit.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ module.exports = [
77
name: 'Core - CDN',
88
path: 'dist/legacy/rudder-analytics.min.js',
99
gzip: true,
10-
limit: '38.1 kB',
10+
limit: '38.9 kB',
1111
},
1212
{
1313
name: 'All Integrations - CDN',
1414
path: 'dist/legacy/js-integrations/*.min.js',
1515
gzip: true,
16-
limit: '716 kB',
16+
limit: '400 kB',
1717
},
1818
{
1919
name: 'Core - NPM',
2020
path: 'dist/npm-lib/index.js',
2121
gzip: true,
22-
limit: '38.1 kB',
22+
limit: '38.9 kB',
2323
},
2424
{
2525
name: 'Service Worker - NPM',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { ErrorReportingService } from '../../../../../src/features/core/metrics/errorReporting/ErrorReportingService';
2+
import logger from '../../../../../src/utils/logUtil';
3+
4+
const errorReportingService = new ErrorReportingService(logger);
5+
const DEFAULT_ERROR_REPORT_PROVIDER = 'rs-bugsnag';
6+
const sourceId = 'random-source-id';
7+
8+
describe('Error reporting service Test suite', () => {
9+
test('Should print error message and return if source config or sourceId is not provided in init call', () => {
10+
const outcome = errorReportingService.init();
11+
expect(outcome).toBe(undefined);
12+
});
13+
test('Should not initialize provider if not enabled from source config in init call', () => {
14+
errorReportingService.init({ statsCollection: { errors: { enabled: false } } }, sourceId);
15+
expect(errorReportingService.isEnabled).toEqual(false);
16+
});
17+
test('Should initialize provider if enabled from source config in init call', async () => {
18+
errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId);
19+
expect(errorReportingService.isEnabled).toEqual(true);
20+
});
21+
test('Should initialize default provider if enabled from source config but provider name is not there', async () => {
22+
window.bugsnag = jest.fn(() => ({ notifier: { version: '6.0.0' } }));
23+
errorReportingService.exposeToGlobal = jest.fn();
24+
errorReportingService.onClientReady = jest.fn(() => errorReportingService.exposeToGlobal());
25+
errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId);
26+
expect(errorReportingService.providerName).toEqual(DEFAULT_ERROR_REPORT_PROVIDER);
27+
expect(errorReportingService.onClientReady).toHaveBeenCalledTimes(1);
28+
expect(errorReportingService.exposeToGlobal).toHaveBeenCalledTimes(1);
29+
});
30+
test('Should not initialize provider if provider from source config does not match with SDK supported list', async () => {
31+
window.bugsnag = undefined;
32+
errorReportingService.init(
33+
{ statsCollection: { errors: { enabled: true, provider: 'test' } } },
34+
sourceId,
35+
);
36+
expect(errorReportingService.provider.client).toEqual(undefined);
37+
expect(errorReportingService.onClientReady).toHaveBeenCalledTimes(0);
38+
});
39+
test('Should not initialize provider if the enabled flag is missing from the source config (default state is to not load)', async () => {
40+
window.bugsnag = undefined;
41+
errorReportingService.init({ statsCollection: { errors: { provider: 'test' } } }, sourceId);
42+
expect(errorReportingService.provider.client).toEqual(undefined);
43+
expect(errorReportingService.onClientReady).toHaveBeenCalledTimes(0);
44+
});
45+
test('Should not initialize provider if the error collection enabled flag is not a boolean', async () => {
46+
window.bugsnag = undefined;
47+
errorReportingService.init(
48+
{ statsCollection: { errors: { enabled: 'true', provider: 'test' } } },
49+
sourceId,
50+
);
51+
expect(errorReportingService.provider.client).toEqual(undefined);
52+
expect(errorReportingService.onClientReady).toHaveBeenCalledTimes(0);
53+
});
54+
});
55+
56+
describe('Bugsnag Test suite', () => {
57+
test('Should not initialize bugsnag if version > 6 of bugsnag is present in window scope', async () => {
58+
window.bugsnag = { _client: { _notifier: { version: '7.0.0' } } };
59+
errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId);
60+
expect(errorReportingService.provider.client).toEqual(undefined);
61+
});
62+
test('Should not initialize bugsnag if version <6 of bugsnag is present in window scope', async () => {
63+
window.bugsnag = jest.fn(() => ({ notifier: { version: '4.0.0' } }));
64+
errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId);
65+
expect(errorReportingService.provider.client).toEqual(undefined);
66+
});
67+
test('Should initialize bugsnag if version 6 of bugsnag is present in window scope', async () => {
68+
window.bugsnag = jest.fn(() => ({ notifier: { version: '6.0.0' } }));
69+
errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId);
70+
expect(errorReportingService.provider.client).not.toBe(undefined);
71+
});
72+
test('Should initialize Bugsnag if provider from source config matches with SDK supported list', async () => {
73+
window.bugsnag = jest.fn(() => ({ notifier: { version: '6.0.0' } }));
74+
errorReportingService.init(
75+
{ statsCollection: { errors: { enabled: true, provider: 'rs-bugsnag' } } },
76+
sourceId,
77+
);
78+
expect(errorReportingService.provider.client).not.toEqual(undefined);
79+
});
80+
});

examples/SampleEventsTest.Html

+72-68
Original file line numberDiff line numberDiff line change
@@ -25,82 +25,86 @@
2525
};
2626
})(method);
2727
}
28+
2829
rudderanalytics.load(
2930
'__WRITE_KEY__',
3031
'__DATAPLANE_URL__',
3132
{ logLevel: "DEBUG" }
3233
);
33-
rudderanalytics.identify(
34-
"customUserID",
35-
{
36-
name: "John Doe",
37-
title: "CEO",
38-
39-
company: "Company123",
40-
phone: "123-456-7890",
41-
rating: "Hot",
42-
city: "Austin",
43-
postalCode: "12345",
44-
country: "US",
45-
street: "Sample Address",
46-
state: "TX",
47-
},
48-
() => {
49-
console.log("in identify call");
50-
}
51-
);
52-
rudderanalytics.page(
53-
"Home",
54-
"Cart Viewed",
55-
{
56-
path: "",
57-
referrer: "",
58-
search: "",
59-
title: "",
60-
url: "",
61-
},
62-
() => {
63-
console.log("in page call");
64-
}
65-
);
6634

67-
rudderanalytics.track(
68-
"test track event 1",
69-
{
70-
revenue: 30,
71-
currency: "USD",
72-
user_actual_id: 12345,
73-
},
74-
() => {
75-
console.log("in track call 1");
76-
}
77-
);
35+
setTimeout(function() {
36+
rudderanalytics.identify(
37+
"customUserID",
38+
{
39+
name: "John Doe",
40+
title: "CEO",
41+
42+
company: "Company123",
43+
phone: "123-456-7890",
44+
rating: "Hot",
45+
city: "Austin",
46+
postalCode: "12345",
47+
country: "US",
48+
street: "Sample Address",
49+
state: "TX",
50+
},
51+
() => {
52+
console.log("in identify call");
53+
}
54+
);
55+
rudderanalytics.page(
56+
"Home",
57+
"Cart Viewed",
58+
{
59+
path: "",
60+
referrer: "",
61+
search: "",
62+
title: "",
63+
url: "",
64+
},
65+
() => {
66+
console.log("in page call");
67+
}
68+
);
7869

79-
rudderanalytics.track(
80-
"test track event 2",
81-
{
82-
revenue: 45,
83-
currency: "INR",
84-
user_actual_id: 333,
85-
},
86-
() => {
87-
console.log("in track call 2");
88-
}
89-
);
70+
rudderanalytics.track(
71+
"test track event 1",
72+
{
73+
revenue: 30,
74+
currency: "USD",
75+
user_actual_id: 12345,
76+
},
77+
() => {
78+
console.log("in track call 1");
79+
}
80+
);
9081

91-
rudderanalytics.track(
92-
"test track event 3",
93-
{
94-
revenue: 10003,
95-
currency: "EUR",
96-
user_actual_id: 5678,
97-
},
98-
() => {
99-
console.log("in track call 3");
100-
}
101-
);
82+
rudderanalytics.track(
83+
"test track event 2",
84+
{
85+
revenue: 45,
86+
currency: "INR",
87+
user_actual_id: 333,
88+
},
89+
() => {
90+
console.log("in track call 2");
91+
}
92+
);
93+
94+
rudderanalytics.track(
95+
"test track event 3",
96+
{
97+
revenue: 10003,
98+
currency: "EUR",
99+
user_actual_id: 5678,
100+
},
101+
() => {
102+
console.log("in track call 3");
103+
}
104+
);
102105

103-
// TODO: Call other APIs here
106+
// TODO: Call other APIs here
107+
}, 5000)
104108
</script>
105109

106110
<!-- ============ V1 ============ -->
@@ -137,7 +141,7 @@
137141
<!-- <script src="../dist/rudder-analytics.min.js"></script> -->
138142

139143
<!-- Local UNMINIFIED -->
140-
<script src="./rudder-analytics.js"></script>
144+
<!-- <script src="./rudder-analytics.js"></script> -->
141145
<!-- ============ LOCAl ================= -->
142146
</head>
143147
<body>

jest.config.js

+4-10
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,13 @@ module.exports = {
1919
// collectCoverage: false,
2020

2121
// An array of glob patterns indicating a set of files for which coverage information should be collected
22-
collectCoverageFrom: [
23-
'packages/**/*.{js,}',
24-
'src/**/*.{js,}',
25-
'!**/*.test.js',
26-
'!**/test/*.js',
27-
],
22+
collectCoverageFrom: ['packages/**/*.{js,}', 'src/**/*.{js,}', '!**/*.test.js', '!**/test/*.js'],
2823

2924
// The directory where Jest should output its coverage files
3025
coverageDirectory: 'reports/coverage',
3126

3227
// An array of regexp pattern strings used to skip coverage collection
33-
coveragePathIgnorePatterns: [
34-
],
28+
coveragePathIgnorePatterns: [],
3529

3630
// A list of reporter names that Jest uses when writing coverage reports
3731
coverageReporters: ['json', 'text', ['lcov', { projectRoot: '/' }], 'clover'],
@@ -151,7 +145,7 @@ module.exports = {
151145

152146
// Options that will be passed to the testEnvironment
153147
testEnvironmentOptions: {
154-
url: 'https://www.test-host.com',
148+
url: 'https://www.rs-unit-test-host.com',
155149
runScripts: 'dangerously',
156150
resources: 'usable',
157151
},
@@ -182,7 +176,7 @@ module.exports = {
182176

183177
// A map from regular expressions to paths to transformers
184178
transform: {
185-
'^.+\\.js?$': ['esbuild-jest', { sourcemap: true }],
179+
'^.+\\.js?$': 'babel-jest',
186180
},
187181

188182
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation

0 commit comments

Comments
 (0)