Repository navigation
Backport #36443 to 2.0: fix CSV import crash on malformed quoted fields - #37214
Conversation
Catch the UncheckedIOException Commons CSV raises for malformed quoted fields in both EntityCsv.parse overloads and report it as PARSER_FAILURE, return null from the recursive overload so recursive imports abort cleanly instead of failing with a 500, and word the abort reason as the line and the fix (characters after a closing quote, unclosed quote) instead of the raw lexer message. (cherry picked from commit d44ad6e)
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
Code Review ✅ Approved🟡 Medium risk · Catching unchecked CSV lexer errors routes malformed imports to ABORTED instead of server errors, so those imports may be rejected without importing records. Backports the CSV import fix so malformed quoted fields abort with a clear parser failure instead of an HTTP 500 or a FAILED async job. Both VerificationRules No rules evaluated Functional validation Not enabledAuto-approval Not enabledFor more verification details, comment OptionsDisplay: compact → Showing compact verification results. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
Describe your changes:
Backport of #36443 to
2.0.On 2.0, importing a CSV with a malformed quoted field (a stray character after a closing quote, or a quote that is never closed) fails with a server error: Commons CSV 1.12 (same version as
main) wraps the lexer error inUncheckedIOException, which bothEntityCsv.parseoverloads let escape. Sync imports return HTTP 500 andimportAsyncjobs end FAILED with the rawCSVExceptiontext.This backport:
UncheckedIOExceptionin bothparseoverloads and reports it asPARSER_FAILURE, so the import returnsABORTED;nullfromparse(csv, true)on a parser failure, so recursive database / schema / service / drive-service imports hit the existingrecords == nullguard inimportCsv(records, ...)instead ofrecords.get(0)on an empty list;CsvParseErrorMessage), e.g.line 2 has characters after the closing quote of a quoted value. ...andline 3 starts a quoted value that is never closed. ..., and fixes the "CSV filed" typo.Conflict resolved: 2.0 does not have
restoreFormulas(#36070 is not on 2.0), so only the newdocumentParserFailurehelper was taken from that hunk. On 2.0,parse(csv)still uses.stream().toList(), which raises the sameUncheckedIOException.Blast radius: only malformed CSVs behave differently. The four 2.0 callers of
parse(csv, recursive)all pass the result toimportCsv(records, ...), which already returns early onnull.Type of change:
Tests:
Unit tests
2.0+ this backport:EntityCsvTest(68),CsvParseErrorMessageTest(3),CsvParseTest(3),CsvUtilTest(10): 84 run, 0 failures.EntityCsv.java:test_importMalformedCsvAbortsWithParserFailureandtest_recursiveImportOfMalformedCsvAbortsWithParserFailureerror with the escaped exception, so the bug is present on 2.0.Live server evidence (from #36443 on
main; same code path and Commons CSV version)UI screen recording:
Not applicable — backend-only change.