Skip to content

Commit f0c72b3

Browse files
committed
Better error messages for CSVReader #35
1 parent 82ee81e commit f0c72b3

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

sources/imperative/reader/Reader.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ extension CSVReader {
285285
reachedRowsEnd = true
286286
break
287287
} else {
288-
throw Error._invalidEscapedField(rowIndex: rowIndex)
288+
let targetField = String(decoding: self._fieldBuffer.flatMap { UTF8.encode($0)! }, as: UTF8.self)
289+
throw Error._invalidEscapedField(rowIndex: rowIndex, field: targetField, nextScalar: followingScalar)
289290
}
290291
}
291292

@@ -326,24 +327,26 @@ fileprivate extension CSVReader.Error {
326327
/// - parameter rowIndex: The location of the row which generated the error.
327328
static func _invalidUnescapedField(rowIndex: Int) -> CSVError<CSVReader> {
328329
.init(.invalidInput,
329-
reason: "Quotes aren't allowed within fields which don't start with quotes.",
330-
help: "Sandwich the targeted field with quotes and escape the quote within the field.",
330+
reason: "The escaping scalar (double quotes by default) is not allowed within fields which aren't already escaped.",
331+
help: "Add the escaping scalar add the very beginning and the very end of the field and escape the escaping scalar found within the field.",
331332
userInfo: ["Row index": rowIndex])
332333
}
333334
/// Error raised when an EOF has been received but the last CSV field was not finalized.
334335
/// - parameter rowIndex: The location of the row which generated the error.
335336
static func _invalidEOF(rowIndex: Int) -> CSVError<CSVReader> {
336337
.init(.invalidInput,
337-
reason: "The last field is escaped (through quotes) and an EOF (End of File) was encountered before the field was properly closed (with a final quote character).",
338-
help: "End the targeted field with a quote.",
338+
reason: "The last field is escaped (with double quotes if you haven't changed the defaults) and an EOF (End of File) was encountered before the field matched at the end with the closing escaping scalar.",
339+
help: "End the targeted field with the scaping scalar (double quotes by default).",
339340
userInfo: ["Row index": rowIndex])
340341
}
341342
/// Error raised when an escaped field hasn't been properly finalized.
342343
/// - parameter rowIndex: The location of the row which generated the error.
343-
static func _invalidEscapedField(rowIndex: Int) -> CSVError<CSVReader> {
344+
/// - parameter field: The content of the escaped field.
345+
static func _invalidEscapedField(rowIndex: Int, field: String, nextScalar: Unicode.Scalar) -> CSVError<CSVReader> {
344346
.init(.invalidInput,
345-
reason: "The last field is escaped (through quotes) and an EOF (End of File) was encountered before the field was properly closed (with a final quote character).",
346-
help: "End the targeted field with a quote.",
347-
userInfo: ["Row index": rowIndex])
347+
reason: "The targeted field parsed successfully. However, the character right after it was not a field nor row delimiter.",
348+
help: (nextScalar == "\r") ? #"If your CSV is CRLF, change the row delimiter to "\r\n" or add a trim strategy for "\r"."#
349+
: "There seems to be some characters after the escaping character and before the next field or the end of the row. Please remove those.",
350+
userInfo: ["Row index": rowIndex, "Field": field])
348351
}
349352
}

0 commit comments

Comments
 (0)