fix(log-list): coerce non-string summary elements instead of throwing#424
Conversation
TimeFusion's to_jsonb re-parsed JSON-looking text[] elements into objects (fixed in timefusion#53), making parseSummaryElement throw 'e.indexOf is not a function' and render whole rows as errors. Stringify non-string elements in parseSummaryData so one bad element degrades to its original text instead of killing the row; also covers older TF binaries still deployed.
Code ReviewOverviewMinimal, targeted bug fix: Issues / Suggestions1.
if (Array.isArray(summary))
return summary.map((e) => (typeof e === 'string' ? e : (JSON.stringify(e) ?? '')));This can't come from 2. Unnecessary allocations in the common (all-strings) path Since if (Array.isArray(summary))
return summary.every((e) => typeof e === 'string')
? (summary as string[])
: summary.map((e) => (typeof e === 'string' ? e : (JSON.stringify(e) ?? '')));Not required given the cache, but worth knowing. 3. Style nit: redundant parentheses The wrapping 4. Comment justification The comment explains a real upstream workaround (TF SummaryThe fix is correct and well-scoped. The only actionable item is guarding the |
Code ReviewOverviewMinimal, targeted fix: coerces non-string elements in the Issues / Suggestions1. Redundant outer parentheses (style)
// current — outer parens are no-ops
summary.map((e) => (typeof e === 'string' ? e : JSON.stringify(e) ?? ''))
// simpler
summary.map(e => typeof e === 'string' ? e : JSON.stringify(e) ?? '')2. The
3. No regression test There are existing test files ( it('parseSummaryData coerces non-string elements', () => {
// simulate what to_jsonb produces: an object instead of a string
const result = parseSummaryData([..., [{ key: 'val' }, 'plain string']]);
expect(result).toEqual(['{"key":"val"}', 'plain string']);
});4. Upstream issue reference (minor) Linking to the upstream fix ( SummaryThe fix is correct and the blast radius is perfectly minimal (+3 / -1). Points 1–2 are stylistic; the only substantive ask is a regression test (point 3). |
Code ReviewOverall: Correct, minimal fix. The Succinctness nitThe outer parentheses wrapping the ternary are redundant. Because // current (outer parens redundant)
summary.map((e) => (typeof e === 'string' ? e : JSON.stringify(e) ?? ''))
// tighter
summary.map(e => typeof e === 'string' ? e : JSON.stringify(e) ?? '')Comment verbosityThe 2-line comment can be collapsed to one line; the upstream issue number carries the key context: // Guard against to_jsonb re-parsing text[] elements (monoscope-tech/timefusion#53).Minor correctness note
No blocking issues — the fix is correct and well-scoped. |
When TimeFusion reads are enabled,
to_jsonb(summary)re-parses JSON-lookingtext[]elements into objects (root cause fixed in monoscope-tech/timefusion#53).parseSummaryElementthen calls.indexOfon a non-string and the whole row renders as "Error rendering row: e.indexOf is not a function".parseSummaryDatanow stringifies non-string elements —JSON.stringifyof the mis-parsed value reproduces the original element text, so rows render correctly even against TF binaries that predate the upstream fix.