From e75261bd83250751c81ba45516c314ad9a99c0a3 Mon Sep 17 00:00:00 2001 From: dimknaf <136385722+dimknaf@users.noreply.github.com> Date: Fri, 8 May 2026 15:05:18 +0100 Subject: [PATCH] fix(frontend/csvParser): accept single-column CSVs without a detectable delimiter PapaParse appends a `Delimiter / UndetectableDelimiter` warning to `results.errors` when the sample contains none of `,` `\t` `|` `;` (e.g. a single-column CSV). The data still parses correctly using the default `,` fallback, so the warning is informational. `parseCSV` was rejecting on any non-empty `results.errors`, so a valid single-column CSV produced the alert "Error parsing CSV file. Please ensure it is a valid CSV." Filter that specific `{type, code}` pair out of the error array before deciding whether to reject. All other PapaParse error codes (`MissingQuotes`, `TooManyFields`, etc.) remain fatal. Adds a unit test mirroring a real failing CSV (header + tickers, CRLF, no delimiter chars). It fails on master, passes with the filter applied. --- frontend/__tests__/csvParser.test.ts | 13 +++++++++++++ frontend/lib/csvParser.ts | 11 +++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/frontend/__tests__/csvParser.test.ts b/frontend/__tests__/csvParser.test.ts index ae5c88d..1d8202b 100644 --- a/frontend/__tests__/csvParser.test.ts +++ b/frontend/__tests__/csvParser.test.ts @@ -59,4 +59,17 @@ describe('parseCSV', () => { expect(result.headers).toEqual(['a', 'b', 'c']); expect(result.rows).toEqual([]); }); + + it('parses a single-column CSV (no delimiter character anywhere)', async () => { + // Mirrors test_symbols_failed.csv: header + tickers, CRLF line endings, + // no commas/tabs/pipes/semicolons. PapaParse can't auto-detect a delimiter + // and emits an "UndetectableDelimiter" warning; the data still parses fine. + const csv = 'Symbol\r\nAMZN\r\nCRSR\r\nAMD\r\nMSFT\r\n0700.HK\r\n'; + const result = await parseCSV(fileFromString(csv)); + + expect(result.headers).toEqual(['Symbol']); + expect(result.rows).toHaveLength(5); + expect(result.rows[0]).toEqual({ Symbol: 'AMZN' }); + expect(result.rows[4]).toEqual({ Symbol: '0700.HK' }); + }); }); diff --git a/frontend/lib/csvParser.ts b/frontend/lib/csvParser.ts index c3626c4..3b2c35b 100644 --- a/frontend/lib/csvParser.ts +++ b/frontend/lib/csvParser.ts @@ -8,8 +8,15 @@ export const parseCSV = (file: File): Promise => { dynamicTyping: true, skipEmptyLines: true, complete: (results) => { - if (results.errors.length > 0) { - reject(new Error(results.errors[0].message)); + // PapaParse emits a non-fatal "UndetectableDelimiter" warning when the + // sample contains none of `,` `\t` `|` `;` (e.g. a single-column CSV). + // The data still parses correctly using the default `,` delimiter, + // so this warning is informational — drop it before deciding to reject. + const fatalErrors = results.errors.filter( + (e) => !(e.type === 'Delimiter' && e.code === 'UndetectableDelimiter') + ); + if (fatalErrors.length > 0) { + reject(new Error(fatalErrors[0].message)); return; }