Skip to content

Commit 3639780

Browse files
committed
fix(csv-parse): improve INVALID_OPENING_QUOTE error message (fix adaltas/node-csv-docs#120)
1 parent 9fcd6da commit 3639780

17 files changed

+87
-47
lines changed

packages/csv-parse/dist/cjs/index.cjs

+7-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const is_object = function(obj){
88

99
class CsvError extends Error {
1010
constructor(code, message, options, ...contexts) {
11-
if(Array.isArray(message)) message = message.join(' ');
11+
if(Array.isArray(message)) message = message.join(' ').trim();
1212
super(message);
1313
if(Error.captureStackTrace !== undefined){
1414
Error.captureStackTrace(this, CsvError);
@@ -639,7 +639,7 @@ const transform = function(original_options = {}) {
639639
},
640640
// Central parser implementation
641641
parse: function(nextBuf, end, push, close){
642-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
642+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
643643
let {comment, escape, quote, record_delimiter} = this.options;
644644
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
645645
let buf;
@@ -775,11 +775,14 @@ const transform = function(original_options = {}) {
775775
if(this.state.field.length !== 0){
776776
// In relax_quotes mode, treat opening quote preceded by chrs as regular
777777
if(relax_quotes === false){
778+
const info = this.__infoField();
779+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
778780
const err = this.__error(
779781
new CsvError('INVALID_OPENING_QUOTE', [
780782
'Invalid Opening Quote:',
781-
`a quote is found inside a field at line ${this.info.lines}`,
782-
], this.options, this.__infoField(), {
783+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
784+
bom ? `(${bom} bom)` : undefined
785+
], this.options, info, {
783786
field: this.state.field,
784787
})
785788
);

packages/csv-parse/dist/cjs/sync.cjs

+7-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
class CsvError extends Error {
44
constructor(code, message, options, ...contexts) {
5-
if(Array.isArray(message)) message = message.join(' ');
5+
if(Array.isArray(message)) message = message.join(' ').trim();
66
super(message);
77
if(Error.captureStackTrace !== undefined){
88
Error.captureStackTrace(this, CsvError);
@@ -637,7 +637,7 @@ const transform = function(original_options = {}) {
637637
},
638638
// Central parser implementation
639639
parse: function(nextBuf, end, push, close){
640-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
640+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
641641
let {comment, escape, quote, record_delimiter} = this.options;
642642
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
643643
let buf;
@@ -773,11 +773,14 @@ const transform = function(original_options = {}) {
773773
if(this.state.field.length !== 0){
774774
// In relax_quotes mode, treat opening quote preceded by chrs as regular
775775
if(relax_quotes === false){
776+
const info = this.__infoField();
777+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
776778
const err = this.__error(
777779
new CsvError('INVALID_OPENING_QUOTE', [
778780
'Invalid Opening Quote:',
779-
`a quote is found inside a field at line ${this.info.lines}`,
780-
], this.options, this.__infoField(), {
781+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
782+
bom ? `(${bom} bom)` : undefined
783+
], this.options, info, {
781784
field: this.state.field,
782785
})
783786
);

packages/csv-parse/dist/esm/index.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -5066,7 +5066,7 @@ const is_object = function(obj){
50665066

50675067
class CsvError extends Error {
50685068
constructor(code, message, options, ...contexts) {
5069-
if(Array.isArray(message)) message = message.join(' ');
5069+
if(Array.isArray(message)) message = message.join(' ').trim();
50705070
super(message);
50715071
if(Error.captureStackTrace !== undefined){
50725072
Error.captureStackTrace(this, CsvError);
@@ -5697,7 +5697,7 @@ const transform = function(original_options = {}) {
56975697
},
56985698
// Central parser implementation
56995699
parse: function(nextBuf, end, push, close){
5700-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
5700+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
57015701
let {comment, escape, quote, record_delimiter} = this.options;
57025702
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
57035703
let buf;
@@ -5833,11 +5833,14 @@ const transform = function(original_options = {}) {
58335833
if(this.state.field.length !== 0){
58345834
// In relax_quotes mode, treat opening quote preceded by chrs as regular
58355835
if(relax_quotes === false){
5836+
const info = this.__infoField();
5837+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
58365838
const err = this.__error(
58375839
new CsvError('INVALID_OPENING_QUOTE', [
58385840
'Invalid Opening Quote:',
5839-
`a quote is found inside a field at line ${this.info.lines}`,
5840-
], this.options, this.__infoField(), {
5841+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
5842+
bom ? `(${bom} bom)` : undefined
5843+
], this.options, info, {
58415844
field: this.state.field,
58425845
})
58435846
);

packages/csv-parse/dist/esm/sync.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -1972,7 +1972,7 @@ function isSlowBuffer (obj) {
19721972

19731973
class CsvError extends Error {
19741974
constructor(code, message, options, ...contexts) {
1975-
if(Array.isArray(message)) message = message.join(' ');
1975+
if(Array.isArray(message)) message = message.join(' ').trim();
19761976
super(message);
19771977
if(Error.captureStackTrace !== undefined){
19781978
Error.captureStackTrace(this, CsvError);
@@ -2607,7 +2607,7 @@ const transform = function(original_options = {}) {
26072607
},
26082608
// Central parser implementation
26092609
parse: function(nextBuf, end, push, close){
2610-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
2610+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
26112611
let {comment, escape, quote, record_delimiter} = this.options;
26122612
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
26132613
let buf;
@@ -2743,11 +2743,14 @@ const transform = function(original_options = {}) {
27432743
if(this.state.field.length !== 0){
27442744
// In relax_quotes mode, treat opening quote preceded by chrs as regular
27452745
if(relax_quotes === false){
2746+
const info = this.__infoField();
2747+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
27462748
const err = this.__error(
27472749
new CsvError('INVALID_OPENING_QUOTE', [
27482750
'Invalid Opening Quote:',
2749-
`a quote is found inside a field at line ${this.info.lines}`,
2750-
], this.options, this.__infoField(), {
2751+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
2752+
bom ? `(${bom} bom)` : undefined
2753+
], this.options, info, {
27512754
field: this.state.field,
27522755
})
27532756
);

packages/csv-parse/dist/iife/index.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -5069,7 +5069,7 @@ var csv_parse = (function (exports) {
50695069

50705070
class CsvError extends Error {
50715071
constructor(code, message, options, ...contexts) {
5072-
if(Array.isArray(message)) message = message.join(' ');
5072+
if(Array.isArray(message)) message = message.join(' ').trim();
50735073
super(message);
50745074
if(Error.captureStackTrace !== undefined){
50755075
Error.captureStackTrace(this, CsvError);
@@ -5700,7 +5700,7 @@ var csv_parse = (function (exports) {
57005700
},
57015701
// Central parser implementation
57025702
parse: function(nextBuf, end, push, close){
5703-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
5703+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
57045704
let {comment, escape, quote, record_delimiter} = this.options;
57055705
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
57065706
let buf;
@@ -5836,11 +5836,14 @@ var csv_parse = (function (exports) {
58365836
if(this.state.field.length !== 0){
58375837
// In relax_quotes mode, treat opening quote preceded by chrs as regular
58385838
if(relax_quotes === false){
5839+
const info = this.__infoField();
5840+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
58395841
const err = this.__error(
58405842
new CsvError('INVALID_OPENING_QUOTE', [
58415843
'Invalid Opening Quote:',
5842-
`a quote is found inside a field at line ${this.info.lines}`,
5843-
], this.options, this.__infoField(), {
5844+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
5845+
bom ? `(${bom} bom)` : undefined
5846+
], this.options, info, {
58445847
field: this.state.field,
58455848
})
58465849
);

packages/csv-parse/dist/iife/sync.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -1975,7 +1975,7 @@ var csv_parse_sync = (function (exports) {
19751975

19761976
class CsvError extends Error {
19771977
constructor(code, message, options, ...contexts) {
1978-
if(Array.isArray(message)) message = message.join(' ');
1978+
if(Array.isArray(message)) message = message.join(' ').trim();
19791979
super(message);
19801980
if(Error.captureStackTrace !== undefined){
19811981
Error.captureStackTrace(this, CsvError);
@@ -2610,7 +2610,7 @@ var csv_parse_sync = (function (exports) {
26102610
},
26112611
// Central parser implementation
26122612
parse: function(nextBuf, end, push, close){
2613-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
2613+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
26142614
let {comment, escape, quote, record_delimiter} = this.options;
26152615
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
26162616
let buf;
@@ -2746,11 +2746,14 @@ var csv_parse_sync = (function (exports) {
27462746
if(this.state.field.length !== 0){
27472747
// In relax_quotes mode, treat opening quote preceded by chrs as regular
27482748
if(relax_quotes === false){
2749+
const info = this.__infoField();
2750+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
27492751
const err = this.__error(
27502752
new CsvError('INVALID_OPENING_QUOTE', [
27512753
'Invalid Opening Quote:',
2752-
`a quote is found inside a field at line ${this.info.lines}`,
2753-
], this.options, this.__infoField(), {
2754+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
2755+
bom ? `(${bom} bom)` : undefined
2756+
], this.options, info, {
27542757
field: this.state.field,
27552758
})
27562759
);

packages/csv-parse/dist/umd/index.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -5072,7 +5072,7 @@
50725072

50735073
class CsvError extends Error {
50745074
constructor(code, message, options, ...contexts) {
5075-
if(Array.isArray(message)) message = message.join(' ');
5075+
if(Array.isArray(message)) message = message.join(' ').trim();
50765076
super(message);
50775077
if(Error.captureStackTrace !== undefined){
50785078
Error.captureStackTrace(this, CsvError);
@@ -5703,7 +5703,7 @@
57035703
},
57045704
// Central parser implementation
57055705
parse: function(nextBuf, end, push, close){
5706-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
5706+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
57075707
let {comment, escape, quote, record_delimiter} = this.options;
57085708
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
57095709
let buf;
@@ -5839,11 +5839,14 @@
58395839
if(this.state.field.length !== 0){
58405840
// In relax_quotes mode, treat opening quote preceded by chrs as regular
58415841
if(relax_quotes === false){
5842+
const info = this.__infoField();
5843+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
58425844
const err = this.__error(
58435845
new CsvError('INVALID_OPENING_QUOTE', [
58445846
'Invalid Opening Quote:',
5845-
`a quote is found inside a field at line ${this.info.lines}`,
5846-
], this.options, this.__infoField(), {
5847+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
5848+
bom ? `(${bom} bom)` : undefined
5849+
], this.options, info, {
58475850
field: this.state.field,
58485851
})
58495852
);

packages/csv-parse/dist/umd/sync.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -1978,7 +1978,7 @@
19781978

19791979
class CsvError extends Error {
19801980
constructor(code, message, options, ...contexts) {
1981-
if(Array.isArray(message)) message = message.join(' ');
1981+
if(Array.isArray(message)) message = message.join(' ').trim();
19821982
super(message);
19831983
if(Error.captureStackTrace !== undefined){
19841984
Error.captureStackTrace(this, CsvError);
@@ -2613,7 +2613,7 @@
26132613
},
26142614
// Central parser implementation
26152615
parse: function(nextBuf, end, push, close){
2616-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
2616+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
26172617
let {comment, escape, quote, record_delimiter} = this.options;
26182618
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
26192619
let buf;
@@ -2749,11 +2749,14 @@
27492749
if(this.state.field.length !== 0){
27502750
// In relax_quotes mode, treat opening quote preceded by chrs as regular
27512751
if(relax_quotes === false){
2752+
const info = this.__infoField();
2753+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
27522754
const err = this.__error(
27532755
new CsvError('INVALID_OPENING_QUOTE', [
27542756
'Invalid Opening Quote:',
2755-
`a quote is found inside a field at line ${this.info.lines}`,
2756-
], this.options, this.__infoField(), {
2757+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
2758+
bom ? `(${bom} bom)` : undefined
2759+
], this.options, info, {
27572760
field: this.state.field,
27582761
})
27592762
);

packages/csv-parse/lib/api/CsvError.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
class CsvError extends Error {
33
constructor(code, message, options, ...contexts) {
4-
if(Array.isArray(message)) message = message.join(' ');
4+
if(Array.isArray(message)) message = message.join(' ').trim();
55
super(message);
66
if(Error.captureStackTrace !== undefined){
77
Error.captureStackTrace(this, CsvError);

packages/csv-parse/lib/api/index.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const transform = function(original_options = {}) {
6161
},
6262
// Central parser implementation
6363
parse: function(nextBuf, end, push, close){
64-
const {bom, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
64+
const {bom, encoding, from_line, ltrim, max_record_size,raw, relax_quotes, rtrim, skip_empty_lines, to, to_line} = this.options;
6565
let {comment, escape, quote, record_delimiter} = this.options;
6666
const {bomSkipped, previousBuf, rawBuffer, escapeIsQuote} = this.state;
6767
let buf;
@@ -197,11 +197,14 @@ const transform = function(original_options = {}) {
197197
if(this.state.field.length !== 0){
198198
// In relax_quotes mode, treat opening quote preceded by chrs as regular
199199
if(relax_quotes === false){
200+
const info = this.__infoField();
201+
const bom = Object.keys(boms).map(b => boms[b].equals(this.state.field.toString()) ? b : false).filter(Boolean)[0];
200202
const err = this.__error(
201203
new CsvError('INVALID_OPENING_QUOTE', [
202204
'Invalid Opening Quote:',
203-
`a quote is found inside a field at line ${this.info.lines}`,
204-
], this.options, this.__infoField(), {
205+
`a quote is found on field ${JSON.stringify(info.column)} at line ${info.lines}, value is ${JSON.stringify(this.state.field.toString(encoding))}`,
206+
bom ? `(${bom} bom)` : undefined
207+
], this.options, info, {
205208
field: this.state.field,
206209
})
207210
);

packages/csv-parse/test/api.events.coffee

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe 'API events', ->
4646
'''
4747
parser = parse (err) ->
4848
assert_error err,
49-
message: 'Invalid Opening Quote: a quote is found inside a field at line 1'
49+
message: 'Invalid Opening Quote: a quote is found on field 0 at line 1, value is " x "'
5050
code: 'INVALID_OPENING_QUOTE'
5151
field: ' x '
5252
next()

0 commit comments

Comments
 (0)