diff --git a/src/main/java/org/apache/commons/csv/CSVParser.java b/src/main/java/org/apache/commons/csv/CSVParser.java index 24936b6d..5640af65 100644 --- a/src/main/java/org/apache/commons/csv/CSVParser.java +++ b/src/main/java/org/apache/commons/csv/CSVParser.java @@ -462,12 +462,12 @@ public final class CSVParser implements Iterable, Closeable { * * @return parsed CSV content of current reading line */ - private String getLastParsedContent() { + public String getLastParsedContent() { String parsedContent = ""; int recordListSize = this.recordList.size(); if (recordListSize > 0) { if (recordListSize <= this.maxParsedTokenCount) { - parsedContent = String.join("", this.recordList.toArray(Constants.EMPTY_STRING_ARRAY)); + parsedContent = String.join(this.format.getDelimiterString(), this.recordList.toArray(Constants.EMPTY_STRING_ARRAY)); } else { // number of parsed token exceed required token count. Take the expected tokens from the end. int startIndex = recordListSize - maxParsedTokenCount; @@ -810,8 +810,7 @@ public final class CSVParser implements Iterable, Closeable { this.lexer.nextToken(this.reusableToken); } catch (IOException ioe) { String errorMessage = "An exception occurred while tying to parse the CSV content. Issue in line: " - + this.lexer.getCurrentLineNumber() + ", position: " + this.lexer.getCharacterPosition() - + ", last parsed content: " + this.getLastParsedContent(); + + this.lexer.getCurrentLineNumber() + ", position: " + this.lexer.getCharacterPosition(); throw new IOException(errorMessage, ioe); } switch (this.reusableToken.type) { diff --git a/src/test/java/org/apache/commons/csv/CSVParserTest.java b/src/test/java/org/apache/commons/csv/CSVParserTest.java index 142cf56b..70eaa4a7 100644 --- a/src/test/java/org/apache/commons/csv/CSVParserTest.java +++ b/src/test/java/org/apache/commons/csv/CSVParserTest.java @@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.io.IOException; @@ -1643,7 +1644,7 @@ public class CSVParserTest { } @Test - public void testFaultyCSVShouldThrowErrorWithDetailedMessage() { + public void testFaultyCSVShouldThrowErrorAndDetailedMessageShouldBeAvailable_1() { String csvContent = "col1,col2,col3,col4,col5,col6,col7,col8,col9,col10\n" + "rec1,rec2,rec3,rec4,rec5,rec6,rec7,rec8,\"\"rec9\"\",rec10"; @@ -1653,20 +1654,59 @@ public class CSVParserTest { .setSkipHeaderRecord(true) .build(); + CSVParser csvParser = null; + try { + csvParser = csvFormat.parse(stringReader); + } catch (IOException e) { + fail("Failed to parse the CSV content"); + } + final Iterable finalRecords = csvParser; Exception exception = assertThrows(UncheckedIOException.class, () -> { - Iterable records = csvFormat.parse(stringReader); - for (CSVRecord record : records) { + for (CSVRecord record : finalRecords) { System.out.println(record.get(0) + " " + record.get(1) + " " + record.get(2) + " " + record.get(3) + " " + record.get(4) + " " + record.get(5) + " " + record.get(6) + " " + record.get(7) + " " + record.get(8) + " " + record.get(9)); } }); String expectedErrorMessage = "Exception reading next record: java.io.IOException: An exception occurred " + - "while tying to parse the CSV content. Issue in line: 2, position: 94, last parsed content: " + - "...rec4,rec5,rec6,rec7,rec8"; + "while tying to parse the CSV content. Issue in line: 2, position: 94"; String actualMessage = exception.getMessage(); - assertTrue(actualMessage.contains(expectedErrorMessage)); + assertNotNull(csvParser); + String expectedLastParsedContent = "...rec4,rec5,rec6,rec7,rec8"; + assertEquals(expectedLastParsedContent, csvParser.getLastParsedContent()); } + @Test + public void testFaultyCSVShouldThrowErrorAndDetailedMessageShouldBeAvailable_2() { + String csvContent = "col1,col2,col3,col4,col5,col6,col7,col8\n" + + "rec1,rec2,rec3,rec4,\"\"rec5\"\",rec6,rec7,rec8"; + + StringReader stringReader = new StringReader(csvContent); + CSVFormat csvFormat = CSVFormat.DEFAULT.builder() + .setHeader() + .setSkipHeaderRecord(true) + .build(); + + CSVParser csvParser = null; + try { + csvParser = csvFormat.parse(stringReader); + } catch (IOException e) { + fail("Failed to parse the CSV content"); + } + final Iterable finalRecords = csvParser; + Exception exception = assertThrows(UncheckedIOException.class, () -> { + for (CSVRecord record : finalRecords) { + System.out.println(record.get(0) + " " + record.get(1) + " " + record.get(2) + " " + record.get(3) + + " " + record.get(4) + " " + record.get(5) + " " + record.get(6) + " " + record.get(7)); + } + }); + String expectedErrorMessage = "Exception reading next record: java.io.IOException: An exception occurred " + + "while tying to parse the CSV content. Issue in line: 2, position: 63"; + String actualMessage = exception.getMessage(); + assertTrue(actualMessage.contains(expectedErrorMessage)); + assertNotNull(csvParser); + String expectedLastParsedContent = "rec1,rec2,rec3,rec4"; + assertEquals(expectedLastParsedContent, csvParser.getLastParsedContent()); + } }