diff --git a/ui/src/features/common/analysis-modal/transforms.test.ts b/ui/src/features/common/analysis-modal/transforms.test.ts index e3750a498f..aff77b07c4 100644 --- a/ui/src/features/common/analysis-modal/transforms.test.ts +++ b/ui/src/features/common/analysis-modal/transforms.test.ts @@ -24,7 +24,8 @@ import { metricStatusLabel, metricSubstatus, printableCloudWatchQuery, - printableDatadogQuery + printableDatadogQuery, + transformMeasurements } from './transforms'; import { AnalysisStatus, FunctionalStatus } from './types'; @@ -560,3 +561,31 @@ describe('analysis modal transforms', () => { }); }); }); + +describe('transformMeasurements()', () => { + test('plain-text measurement value (e.g. web provider returning "PASS") does not throw', () => { + expect(() => transformMeasurements([], [{ value: 'PASS', phase: 'Successful' }])).not.toThrow(); + }); + + test('plain-text measurement value has no tableValue', () => { + const result = transformMeasurements([], [{ value: 'PASS', phase: 'Successful' }]); + expect(result.measurements[0].tableValue).toBeNull(); + }); + + test('plain-text measurement value has no chart value', () => { + const result = transformMeasurements([], [{ value: 'PASS', phase: 'Successful' }]); + expect(result.measurements[0].chartValue).toBeNull(); + }); + + test('plain-text measurement value does not disable charting for the rest of the series', () => { + const result = transformMeasurements( + [], + [ + { value: '1', phase: 'Successful' }, + { value: 'PASS', phase: 'Successful' }, + { value: '2', phase: 'Successful' } + ] + ); + expect(result.chartable).toBe(true); + }); +}); diff --git a/ui/src/features/common/analysis-modal/transforms.ts b/ui/src/features/common/analysis-modal/transforms.ts index 046ef4f86e..219a60bed7 100644 --- a/ui/src/features/common/analysis-modal/transforms.ts +++ b/ui/src/features/common/analysis-modal/transforms.ts @@ -783,7 +783,22 @@ const transformMeasurementValue = ( }; } - const parsedValue = JSON.parse(value); + let parsedValue; + try { + parsedValue = JSON.parse(value); + } catch { + // this behavior matches rollouts with the following reasoning: + // - canChart == true - just one measurement with this set to false will prevent the chart from being displayed + // - chartValue == null - the chart will just show an absence of a point or a blip for this measurement + // - tableValue == null - while a healthcheck of "PASS" or "OK" might be worth seeing, allowing a string of + // onbounded length could make the table unusable (a stack trace, error message, a failed parsoning because + // a long json string got truncated, etc.) + return { + canChart: true, + chartValue: null, + tableValue: null + }; + } // single number measurement value if (isFiniteNumber(parsedValue)) {