Skip to content

Commit 7f77b61

Browse files
committed
Make max chars in cell error message more helpful
1 parent c8084f6 commit 7f77b61

File tree

3 files changed

+26
-6
lines changed

3 files changed

+26
-6
lines changed

csv-validator-core/src/main/scala/uk/gov/nationalarchives/csv/validator/MetaDataValidator.scala

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -355,15 +355,23 @@ class RowIterator(parser: CsvParser, progress: Option[ProgressFor], maxCharsPerC
355355

356356
private var index = 1
357357
private var current = toRow(Try(parser.parseNext()))
358+
private var potentialHeaderRow: Option[Row] = None
358359

359360
@throws(classOf[IOException])
360361
override def next(): Row = {
361362
val row = current match {
362-
case Success(row) => row
363+
case Success(row) =>
364+
if(index == 1 && potentialHeaderRow.isEmpty) potentialHeaderRow = Some(row) // this is here in case the old API is used that doesn't call 'skipHeader'
365+
row
363366
case Failure(ex: TextParsingException) if(ex.toString.contains("exceeds the maximum number of characters")) =>
367+
val cellLocationMsg =
368+
potentialHeaderRow match {
369+
case Some(headerRow) => s"in the cell located at line: ${ex.getLineIndex}, column: ${headerRow.cells(ex.getColumnIndex).value},"
370+
case None => s"in column ${ex.getColumnIndex + 1} of the header row"
371+
}
372+
364373
val customMessage =
365-
s"The number of characters in the cell located at line: ${ex.getLineIndex + 1}, column: ${ex.getColumnIndex + 1}, " +
366-
s"is larger than the maximum number of characters allowed in a cell ($maxCharsPerCell); increase this limit and re-run."
374+
s"The number of characters $cellLocationMsg is larger than the maximum number of characters allowed in a cell ($maxCharsPerCell); increase this limit and re-run."
367375
throw new Exception(customMessage)
368376
case Failure(ex) => throw ex
369377
}
@@ -385,7 +393,9 @@ class RowIterator(parser: CsvParser, progress: Option[ProgressFor], maxCharsPerC
385393
@throws(classOf[IOException])
386394
def skipHeader(): Row = {
387395
this.index = index - 1
388-
next()
396+
val row = next()
397+
this.potentialHeaderRow = Some(row)
398+
row
389399
}
390400

391401
override def hasNext: Boolean = current match {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
col1,col2
2+
row1Col1,row1Col2LongCellLength

csv-validator-core/src/test/scala/uk/gov/nationalarchives/csv/validator/api/CsvValidatorMaxCharsPerCellSpec.scala

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,19 @@ class CsvValidatorMaxCharsPerCellSpec extends Specification with TestResources {
2525
def app(maxChars: Int=4096) = new CsvValidator with AllErrorsMetaDataValidator { val pathSubstitutions: List[(String, String)] = List[(String,String)](); val enforceCaseSensitivePathChecks = false; val trace = false; val skipFileChecks = false; val maxCharsPerCell: Int = maxChars }
2626
def parse(filePath: String, maxChars: Int=4096): Schema = app(maxChars).parseSchema(TextFile(Paths.get(filePath))) fold (f => throw new IllegalArgumentException(f.toString()), s => s)
2727

28-
"fail if the number of characters in a cell is more than the maxCharsPerCell number" in {
28+
"fail if the number of characters in a cell in the header is more than the maxCharsPerCell number and indicate the column number" in {
2929
val maxCharsAllowed = 2
3030
val validatedNel = app(maxCharsAllowed).validate(TextFile(Paths.get(baseResourcePkgPath).resolve("metaData.csv")), parse(baseResourcePkgPath + "/schema.csvs", maxCharsAllowed), None).swap
3131
validatedNel.toList.head.toList must beEqualTo(
32-
List(FailMessage(ValidationError,"java.lang.Exception: The number of characters in the cell located at line: 1, column: 1, is larger than the maximum number of characters allowed in a cell (2); increase this limit and re-run.",None,None))
32+
List(FailMessage(ValidationError,"java.lang.Exception: The number of characters in column 1 of the header row is larger than the maximum number of characters allowed in a cell (2); increase this limit and re-run.",None,None))
33+
)
34+
}
35+
36+
"fail if the number of characters in a cell in a non-header row is more than the maxCharsPerCell number and indicate the column name" in {
37+
val maxCharsAllowed = 15
38+
val validatedNel = app(maxCharsAllowed).validate(TextFile(Paths.get(baseResourcePkgPath).resolve("metaDataWithALongCellLength.csv")), parse(baseResourcePkgPath + "/schema.csvs"), None).swap
39+
validatedNel.toList.head.toList must beEqualTo(
40+
List(FailMessage(ValidationError,"java.lang.Exception: The number of characters in the cell located at line: 1, column: col2, is larger than the maximum number of characters allowed in a cell (15); increase this limit and re-run.",None,None))
3341
)
3442
}
3543

0 commit comments

Comments
 (0)