Skip to content

Commit ded5449

Browse files
authored
fix: Added extra check for undefined values (#260)
1 parent 4eeb566 commit ded5449

File tree

3 files changed

+58
-6
lines changed

3 files changed

+58
-6
lines changed

Diff for: __tests__/steps/measureStep.spec.ts

+32-2
Original file line numberDiff line numberDiff line change
@@ -139,14 +139,44 @@ describe('measureStep', () => {
139139
},
140140
});
141141
});
142-
it('should return when the start mark doesnt exist', () => {
142+
it('should return when the start mark doesnt exist', () => {
143143
measureSpy = jest.spyOn(WP, 'measure');
144144
// ============ Mock Data ============
145145
jest.spyOn(WP, 'getEntriesByName').mockImplementationOnce(name => {
146146
return [];
147147
});
148148
measureStep('not-valid-step', 'startMark', 'endmark');
149149
expect(measureSpy).toBeCalledTimes(0);
150-
})
150+
});
151+
152+
it('should return when the start mark doesnt exist', () => {
153+
measureSpy = jest.spyOn(WP, 'measure');
154+
jest
155+
.spyOn(WP, 'measure')
156+
// @ts-ignore
157+
.mockImplementationOnce(() => undefined);
158+
// ============ Mock Data ============
159+
jest.spyOn(WP, 'getEntriesByName').mockImplementationOnce(name => {
160+
const entries: Record<string, PerformanceEntry> = {
161+
'mark.start_navigate_to_second_screen_first_journey': {
162+
name: 'mark.start_navigate_to_second_screen_first_journey',
163+
entryType: 'mark',
164+
duration: 0,
165+
startTime: 0,
166+
toJSON: jest.fn(),
167+
},
168+
'mark.loaded_second_screen_first_journey': {
169+
name: 'mark.loaded_second_screen_first_journey',
170+
entryType: 'mark',
171+
duration: 0,
172+
startTime: 100,
173+
toJSON: jest.fn(),
174+
},
175+
};
176+
return [entries[name]] ?? [];
177+
});
178+
measureStep('load_second_screen_first_journey', 'start_navigate_to_second_screen_first_journey', 'start_navigate_to_second_screen_first_journey');
179+
expect(measureSpy).toBeCalledTimes(1); // after the first call that returns undefined, it exits the function and does not call measure again
180+
});
151181
});
152182
});

Diff for: src/steps/measureStep.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,38 @@ export const measureStep = (
1212
const stepMetricName = S + step;
1313
const startMarkExists = WP.getEntriesByName(M + startMark).length > 0;
1414
const endMarkExists = WP.getEntriesByName(M + endMark).length > 0;
15-
if (!endMarkExists || !startMarkExists || !config.steps || !config.steps[step]) {
15+
if (
16+
!endMarkExists ||
17+
!startMarkExists ||
18+
!config.steps ||
19+
!config.steps[step]
20+
) {
1621
return;
1722
}
1823

1924
const { maxOutlierThreshold, vitalsThresholds } =
2025
STEP_THRESHOLDS[config.steps[step].threshold];
2126

2227
const stepMeasure = WP.measure(stepMetricName, M + startMark, M + endMark);
28+
29+
// checking to ensure stepMeasure is defined - it can be undefined
30+
// if measure is called on a mark that has already been measured and cleared
31+
if (!stepMeasure) {
32+
return;
33+
}
34+
2335
const { duration } = stepMeasure;
2436
if (duration <= maxOutlierThreshold) {
2537
const score = getRating(duration, vitalsThresholds);
2638
// Do not want to measure or log negative metrics
2739
if (duration >= 0) {
28-
reportPerf('userJourneyStep', duration, score, { stepName: step }, undefined);
40+
reportPerf(
41+
'userJourneyStep',
42+
duration,
43+
score,
44+
{ stepName: step },
45+
undefined,
46+
);
2947
WP.measure(`step.${step}_vitals_${score}`, {
3048
start: stepMeasure.startTime + stepMeasure.duration,
3149
end: stepMeasure.startTime + stepMeasure.duration,

Diff for: src/steps/measureSteps.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ export const measureSteps = (mark: string) => {
1616
Object.keys(finalSteps).forEach(startMark => {
1717
const possibleSteps = finalSteps[startMark];
1818
possibleSteps.forEach(removeActiveStep);
19+
// Async processing all possible steps
20+
// needs to be async due to clearing previously measured steps and marks.
21+
// If we run all concurrently, there is a chance for a race condition
22+
// where we are adding and deleteing the entries in WP.Performance which caused the measure to fail.
1923
Promise.all(
20-
possibleSteps.map(step => {
24+
possibleSteps.map(async step => {
2125
// measure
22-
measureStep(step, startMark, mark);
26+
await measureStep(step, startMark, mark);
2327
}),
2428
).catch(() => {
2529
// TODO @zizzamia log error

0 commit comments

Comments
 (0)