@@ -355,6 +355,8 @@ public static CSVParser parse(final URL url, final Charset charset, final CSVFor
355355 return new CSVParser (new InputStreamReader (url .openStream (), charset ), format );
356356 }
357357
358+ private int maxParsedTokenCount = 5 ;
359+
358360 private String headerComment ;
359361
360362 private String trailerComment ;
@@ -440,6 +442,44 @@ public CSVParser(final Reader reader, final CSVFormat format, final long charact
440442 this .recordNumber = recordNumber - 1 ;
441443 }
442444
445+ /**
446+ * Return the parsed CSV content of current reading line up until this method is called.
447+ * <p>
448+ * Maximum parsed token length set by the 'maxParsedTokenCount' is considered during the construction of return string.
449+ * </p>
450+ * <p>
451+ * Example:
452+ * </p>
453+ * </p>
454+ * If currently reading CSV record row contains following data and 'maxParsedTokenCount' is set to 5 and current reading position is col7
455+ * </p>
456+ * <pre>
457+ * col1, col2, col3, col4, col5, col6, col7
458+ * </pre>
459+ * <p>
460+ * then this would return following
461+ * </p>
462+ * <pre>
463+ * col3, col4, col5, col6, col7
464+ * </pre>
465+ * @return parsed CSV content of current reading line
466+ */
467+ private String getLastParsedContent (){
468+ String parsedContent = "" ;
469+ int recordListSize = this .recordList .size ();
470+ if (recordListSize > 0 ) {
471+ if (recordListSize <= this .maxParsedTokenCount ) {
472+ parsedContent = String .join ("" , this .recordList .toArray (Constants .EMPTY_STRING_ARRAY ));
473+ } else {
474+ // number of parsed token exceed required token count. Take the expected tokens from the end.
475+ int startIndex = recordListSize - maxParsedTokenCount ;
476+ List <String > lastParsedTokenList = this .recordList .subList (startIndex , recordListSize );
477+ parsedContent = "..." + String .join (this .format .getDelimiterString (), lastParsedTokenList .toArray (Constants .EMPTY_STRING_ARRAY ));
478+ }
479+ }
480+ return parsedContent ;
481+ }
482+
443483 private void addRecordValue (final boolean lastRecord ) {
444484 final String input = this .format .trim (this .reusableToken .content .toString ());
445485 if (lastRecord && input .isEmpty () && this .format .getTrailingDelimiter ()) {
@@ -767,7 +807,15 @@ CSVRecord nextRecord() throws IOException {
767807 final long startCharPosition = lexer .getCharacterPosition () + this .characterOffset ;
768808 do {
769809 this .reusableToken .reset ();
770- this .lexer .nextToken (this .reusableToken );
810+ // https://issues.apache.org/jira/browse/CSV-147
811+ try {
812+ this .lexer .nextToken (this .reusableToken );
813+ } catch (IOException ioe ){
814+ String errorMessage = "An error occurred while tying to parse the CSV content. Error in line: "
815+ + this .lexer .getCurrentLineNumber () + ", position: " + this .lexer .getCharacterPosition ()
816+ + ", last parsed content: " + this .getLastParsedContent ();
817+ throw new IOException (errorMessage , ioe );
818+ }
771819 switch (this .reusableToken .type ) {
772820 case TOKEN :
773821 this .addRecordValue (false );
0 commit comments