convert-csv-to-json 3.28.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,367 @@
1
+ # Error Handling Guide
2
+
3
+ This library provides comprehensive, actionable error messages to help you quickly identify and fix issues when parsing CSV files.
4
+
5
+ ## Error Categories
6
+
7
+ All errors are categorized into specific types that inherit from `CsvParsingError`, making them easier to catch and handle programmatically.
8
+
9
+ ### 1. Input Validation Errors (`InputValidationError`)
10
+
11
+ These errors occur when invalid input is provided to a function.
12
+
13
+ **Example:**
14
+ ```
15
+ InputValidationError: Invalid input: Parameter 'csvString' is required.
16
+ Expected: string
17
+ Received: undefined
18
+ Provide valid CSV content as a string to parse.
19
+ ```
20
+
21
+ **Common causes:**
22
+ - Missing required parameters
23
+ - Wrong data type passed (e.g., number instead of string)
24
+ - Null or undefined values
25
+
26
+ **How to fix:**
27
+ - Verify all required parameters are provided
28
+ - Check that parameters match the expected type
29
+ - Review the function signature in the documentation
30
+
31
+ ### 2. Configuration Errors (`ConfigurationError`)
32
+
33
+ These occur when configuration options conflict with each other or are invalid.
34
+
35
+ **Example:**
36
+ ```
37
+ ConfigurationError: Configuration conflict: supportQuotedField() is enabled,
38
+ but fieldDelimiter is set to '"'.
39
+
40
+ The quote character (") cannot be used as a field delimiter, separator,
41
+ or sub-array delimiter when quoted field support is active.
42
+
43
+ Solutions:
44
+ 1. Use a different character for fieldDelimiter (e.g., '|', '\t', ';')
45
+ 2. Disable supportQuotedField() if your CSV doesn't contain quoted fields
46
+ 3. Refer to RFC 4180 for proper CSV formatting
47
+ ```
48
+
49
+ **Common causes:**
50
+ - Using quote character (`"`) as a delimiter with `supportQuotedField(true)`
51
+ - Invalid header index (not a number)
52
+ - Incompatible configuration combinations
53
+
54
+ **How to fix:**
55
+ - Follow the solutions provided in the error message
56
+ - Ensure `indexHeader()` receives a numeric value
57
+ - Review configuration method combinations in the documentation
58
+
59
+ ### 3. CSV Format Errors (`CsvFormatError`)
60
+
61
+ These occur when the CSV data itself is malformed.
62
+
63
+ **Example - Missing Header:**
64
+ ```
65
+ CsvFormatError: CSV parsing error: No header row found.
66
+ The CSV file appears to be empty or has no valid header line.
67
+
68
+ Solutions:
69
+ 1. Ensure your CSV file contains at least one row (header row)
70
+ 2. Verify the file is not empty or contains only whitespace
71
+ 3. Check if you need to use indexHeader(n) to specify a non-standard header row
72
+ ```
73
+
74
+ **Example - Mismatched Quotes:**
75
+ ```
76
+ CsvFormatError: CSV parsing error: Mismatched quotes detected in CSV.
77
+ A quoted field was not properly closed with a matching quote character.
78
+
79
+ RFC 4180 rules for quoted fields:
80
+ • Fields containing delimiters or quotes MUST be enclosed in double quotes
81
+ • To include a quote within a quoted field, use two consecutive quotes: ""
82
+ • Example: "Smith, John" (name contains comma)
83
+ • Example: "He said ""Hello""" (text contains quotes)
84
+
85
+ Solutions:
86
+ 1. Review your CSV for properly paired quote characters
87
+ 2. Use double quotes ("") to escape quotes within quoted fields
88
+ 3. Ensure all commas within field values are inside quotes
89
+ 4. Enable supportQuotedField(true) if you're using quoted fields
90
+ ```
91
+
92
+ **Common causes:**
93
+ - Empty CSV files
94
+ - Missing or unpaired quote characters
95
+ - Incorrect escaping of quotes within quoted fields
96
+ - Line breaks in unexpected places
97
+
98
+ **How to fix:**
99
+ - Validate your CSV file format with an online CSV validator
100
+ - Check that all quoted fields are properly closed
101
+ - Use double quotes (`""`) to escape quotes within fields
102
+ - Ensure quoted fields span complete records when using `supportQuotedField(true)`
103
+
104
+ ### 4. File Operation Errors (`FileOperationError`)
105
+
106
+ These occur when there are issues reading or writing files.
107
+
108
+ **Example:**
109
+ ```
110
+ FileOperationError: File operation error: Failed to read file.
111
+ File path: /path/to/missing/file.csv
112
+ Reason: ENOENT: no such file or directory, open '/path/to/missing/file.csv'
113
+
114
+ Solutions:
115
+ 1. Verify the file path is correct: /path/to/missing/file.csv
116
+ 2. Check file permissions (read access for input, write access for output)
117
+ 3. Ensure the directory exists and is writable for output files
118
+ 4. Verify the file is not in use by another process
119
+ ```
120
+
121
+ **Common causes:**
122
+ - File path is incorrect or doesn't exist
123
+ - Insufficient file permissions
124
+ - Output directory doesn't exist
125
+ - File is locked by another process
126
+
127
+ **How to fix:**
128
+ - Use absolute paths or verify relative paths are correct
129
+ - Check file permissions: `ls -l filename.csv`
130
+ - Create output directories before writing: `mkdir -p output_dir`
131
+ - Close any applications that may have the file open
132
+ - Verify encoding if dealing with special characters
133
+
134
+ ### 5. JSON Validation Errors (`JsonValidationError`)
135
+
136
+ These occur when parsed CSV generates invalid JSON.
137
+
138
+ **Example:**
139
+ ```
140
+ JsonValidationError: JSON validation error: The parsed CSV data generated
141
+ invalid JSON. This typically indicates malformed field names or values in the CSV.
142
+
143
+ Original error: Unexpected token } in JSON at position 45
144
+
145
+ Solutions:
146
+ 1. Check that field names are valid JavaScript identifiers
147
+ 2. Review the CSV data for special characters that aren't properly escaped
148
+ 3. Enable supportQuotedField(true) for fields containing special characters
149
+ 4. Verify that formatValueByType() isn't converting values incorrectly
150
+ ```
151
+
152
+ **Common causes:**
153
+ - Invalid characters in header/field names
154
+ - Special characters not properly escaped in values
155
+ - Circular references or invalid JSON structures
156
+ - Field names conflicting with JavaScript reserved words
157
+
158
+ **How to fix:**
159
+ - Ensure header names follow JavaScript identifier rules (alphanumeric, underscore, dollar sign)
160
+ - Enable `supportQuotedField(true)` for complex values
161
+ - Review special characters in your CSV
162
+ - Use `formatValueByType(false)` if value conversion is causing issues
163
+
164
+ ### 6. Browser API Errors (`BrowserApiError`)
165
+
166
+ These are specific to browser environments using the FileReader API.
167
+
168
+ **Example - FileReader Not Available:**
169
+ ```
170
+ BrowserApiError: Browser compatibility error: FileReader API is not available.
171
+ Your browser does not support the FileReader API required for file parsing.
172
+
173
+ Solutions:
174
+ 1. Use a modern browser that supports FileReader (Chrome 13+, Firefox 10+, Safari 6+)
175
+ 2. Consider using csvStringToJson() or csvStringToJsonAsync() for string-based parsing
176
+ 3. Implement a polyfill or alternative file reading method
177
+ ```
178
+
179
+ **Example - File Parse Error:**
180
+ ```
181
+ BrowserApiError: Browser file parsing error: Failed to read and parse the file.
182
+ Error details: Unexpected end of JSON input
183
+
184
+ Solutions:
185
+ 1. Verify the file is a valid CSV file
186
+ 2. Check the file encoding (UTF-8 is recommended)
187
+ 3. Try a smaller file to isolate the issue
188
+ 4. Check browser console for additional error details
189
+ ```
190
+
191
+ **Common causes:**
192
+ - Using older browsers that don't support FileReader
193
+ - File encoding issues (non-UTF-8)
194
+ - Corrupted file data
195
+ - Cross-origin restrictions
196
+
197
+ **How to fix:**
198
+ - Update to a modern browser
199
+ - Use string-based methods for alternative file sources
200
+ - Ensure files are UTF-8 encoded
201
+ - Check browser console for detailed error information
202
+
203
+ ## Error Handling in Code
204
+
205
+ ### Synchronous Example
206
+
207
+ ```js
208
+ const csvToJson = require('convert-csv-to-json');
209
+
210
+ try {
211
+ const data = csvToJson
212
+ .fieldDelimiter(',')
213
+ .supportQuotedField(true)
214
+ .getJsonFromCsv('data.csv');
215
+
216
+ console.log(`Parsed ${data.length} records`);
217
+ } catch (error) {
218
+ // Access error details programmatically
219
+ if (error.name === 'ConfigurationError') {
220
+ console.error('Fix your configuration:', error.message);
221
+ } else if (error.name === 'FileOperationError') {
222
+ console.error('Check file path and permissions:', error.context.filePath);
223
+ } else if (error.name === 'CsvFormatError') {
224
+ console.error('Fix your CSV file:', error.message);
225
+ } else {
226
+ console.error('Unknown error:', error);
227
+ }
228
+ }
229
+ ```
230
+
231
+ ### Asynchronous Example
232
+
233
+ ```js
234
+ const csvToJson = require('convert-csv-to-json');
235
+
236
+ async function processCSV() {
237
+ try {
238
+ const data = await csvToJson
239
+ .fieldDelimiter(',')
240
+ .formatValueByType()
241
+ .getJsonFromCsvAsync('data.csv');
242
+
243
+ return data;
244
+ } catch (error) {
245
+ // Handle specific error types
246
+ switch (error.name) {
247
+ case 'InputValidationError':
248
+ console.error('Invalid input provided');
249
+ break;
250
+ case 'FileOperationError':
251
+ console.error(`Cannot read file: ${error.context.filePath}`);
252
+ break;
253
+ case 'CsvFormatError':
254
+ console.error('CSV format is invalid');
255
+ break;
256
+ default:
257
+ console.error('Unexpected error:', error);
258
+ }
259
+
260
+ // Re-throw or handle as needed
261
+ throw error;
262
+ }
263
+ }
264
+ ```
265
+
266
+ ### Browser Example
267
+
268
+ ```js
269
+ const { browser } = require('convert-csv-to-json');
270
+
271
+ async function handleFileUpload(event) {
272
+ const file = event.target.files[0];
273
+
274
+ try {
275
+ const data = await browser.parseFile(file);
276
+ console.log(`Loaded ${data.length} records`);
277
+ } catch (error) {
278
+ if (error.name === 'BrowserApiError') {
279
+ if (error.message.includes('FileReader')) {
280
+ // Fallback to string parsing
281
+ console.warn('FileReader not available, use string parsing instead');
282
+ }
283
+ }
284
+
285
+ // Display user-friendly error message
286
+ alert(`Error: ${error.message.split('\n')[0]}`);
287
+ }
288
+ }
289
+ ```
290
+
291
+ ## Error Properties
292
+
293
+ All custom errors include helpful properties for programmatic handling:
294
+
295
+ ```js
296
+ try {
297
+ csvToJson.getJsonFromCsv('file.csv');
298
+ } catch (error) {
299
+ console.log(error.name); // e.g., 'FileOperationError'
300
+ console.log(error.code); // e.g., 'FILE_OPERATION_ERROR'
301
+ console.log(error.message); // Full error message with solutions
302
+ console.log(error.context); // Object with error details
303
+ console.log(error.context.operation); // e.g., 'read'
304
+ console.log(error.context.filePath); // e.g., '/path/to/file.csv'
305
+ }
306
+ ```
307
+
308
+ ## Best Practices
309
+
310
+ 1. **Always use try-catch** for error handling
311
+ 2. **Check error types** to provide specific recovery strategies
312
+ 3. **Log or display helpful context** from `error.message`
313
+ 4. **Test edge cases** like empty files, special characters, and encodings
314
+ 5. **Validate CSV format** before processing with this library
315
+ 6. **Use semantic versioning** - error message improvements are non-breaking
316
+
317
+ ## Debugging Tips
318
+
319
+ ### Enable Verbose Logging
320
+
321
+ ```js
322
+ const csvToJson = require('convert-csv-to-json');
323
+
324
+ try {
325
+ const data = csvToJson.getJsonFromCsv('data.csv');
326
+ } catch (error) {
327
+ // Print full error object for debugging
328
+ console.error('Full error object:', error);
329
+ console.error('Stack trace:', error.stack);
330
+ }
331
+ ```
332
+
333
+ ### Test with Valid CSV
334
+
335
+ ```csv
336
+ firstName,lastName,email
337
+ John,Doe,john@example.com
338
+ "Smith, Jr.",Jane,jane@example.com
339
+ ```
340
+
341
+ ### Validate Your CSV
342
+
343
+ Use online CSV validators:
344
+ - https://csvlint.io/
345
+ - https://www.csvquickio.com/validator
346
+ - https://www.textfixer.com/tools/csv-validator
347
+
348
+ ## Getting Help
349
+
350
+ If you encounter an error:
351
+
352
+ 1. Read the error message carefully - it includes solutions
353
+ 2. Check the relevant section in this guide
354
+ 3. Review [RFC 4180](https://tools.ietf.org/html/rfc4180) for CSV standards
355
+ 4. Search existing [GitHub issues](https://github.com/iuccio/csvToJson/issues)
356
+ 5. Create a new issue with:
357
+ - Full error message
358
+ - Your CSV sample (redacted if sensitive)
359
+ - Your Node.js version
360
+ - Your configuration code
361
+
362
+ ## See Also
363
+
364
+ - [RFC 4180 CSV Standard](https://tools.ietf.org/html/rfc4180)
365
+ - [SYNC.md](./SYNC.md) - Synchronous API reference
366
+ - [ASYNC.md](./ASYNC.md) - Asynchronous API reference
367
+ - [BROWSER.md](./BROWSER.md) - Browser API reference
@@ -0,0 +1,196 @@
1
+ # mapRows Feature - Usage Guide
2
+
3
+ The `mapRows()` feature allows you to transform, filter, or enrich each CSV row after conversion to JSON.
4
+
5
+ ## Basic Usage
6
+
7
+ ### Transform Rows
8
+
9
+ ```javascript
10
+ const csvToJson = require('convert-csv-to-json');
11
+
12
+ // Transform each row - uppercase the firstName
13
+ const result = csvToJson
14
+ .fieldDelimiter(',')
15
+ .mapRows((row, index) => {
16
+ row.firstName = row.firstName.toUpperCase();
17
+ return row;
18
+ })
19
+ .getJsonFromCsv('input.csv');
20
+ ```
21
+
22
+ ### Add New Properties
23
+
24
+ ```javascript
25
+ // Add computed properties to each row
26
+ const result = csvToJson
27
+ .fieldDelimiter(',')
28
+ .mapRows((row, index) => {
29
+ row.rowNumber = index + 1;
30
+ row.fullName = `${row.firstName} ${row.lastName}`;
31
+ return row;
32
+ })
33
+ .csvStringToJson(csvString);
34
+ ```
35
+
36
+ ### Filter Rows
37
+
38
+ ```javascript
39
+ // Filter out rows that don't match a condition
40
+ const result = csvToJson
41
+ .fieldDelimiter(',')
42
+ .mapRows((row) => {
43
+ // Only keep rows where age >= 30
44
+ if (parseInt(row.age) >= 30) {
45
+ return row;
46
+ }
47
+ return null; // Filters out this row
48
+ })
49
+ .getJsonFromCsv('input.csv');
50
+ ```
51
+
52
+ ### Complex Row Transformation
53
+
54
+ ```javascript
55
+ // Transform the entire row structure
56
+ const result = csvToJson
57
+ .fieldDelimiter(',')
58
+ .mapRows((row, index) => {
59
+ return {
60
+ id: index,
61
+ person: {
62
+ name: `${row.firstName} ${row.lastName}`,
63
+ email: row.email
64
+ },
65
+ metadata: {
66
+ processed: true,
67
+ timestamp: new Date().toISOString()
68
+ }
69
+ };
70
+ })
71
+ .getJsonFromCsv('input.csv');
72
+ ```
73
+
74
+ ## API
75
+
76
+ ### `mapRows(mapperFunction)`
77
+
78
+ **Parameters:**
79
+ - `mapperFunction` (Function): A callback function that transforms each row
80
+ - Parameters:
81
+ - `row` (Object): The JSON object representing the current row
82
+ - `index` (Number): The 0-based index of the current row
83
+ - Return value:
84
+ - Return the (possibly modified) row object to keep the row
85
+ - Return `null` or `undefined` to filter out the row
86
+
87
+ **Returns:** `this` for method chaining
88
+
89
+ **Throws:** `TypeError` if mapperFn is not a function
90
+
91
+ ## Examples
92
+
93
+ ### Example 1: Data Validation and Cleaning
94
+
95
+ ```javascript
96
+ const result = csvToJson
97
+ .fieldDelimiter(',')
98
+ .formatValueByType(true)
99
+ .mapRows((row) => {
100
+ // Clean email
101
+ row.email = row.email.toLowerCase().trim();
102
+
103
+ // Validate age
104
+ if (row.age < 0 || row.age > 150) {
105
+ return null; // Filter invalid rows
106
+ }
107
+
108
+ return row;
109
+ })
110
+ .getJsonFromCsv('data.csv');
111
+ ```
112
+
113
+ ### Example 2: Data Enrichment
114
+
115
+ ```javascript
116
+ const result = csvToJson
117
+ .fieldDelimiter(',')
118
+ .mapRows((row, index) => {
119
+ // Add ID and processing date
120
+ row.id = index + 1000;
121
+ row.processedDate = new Date().toISOString();
122
+
123
+ // Categorize by age
124
+ if (row.age < 18) {
125
+ row.category = 'minor';
126
+ } else if (row.age < 65) {
127
+ row.category = 'adult';
128
+ } else {
129
+ row.category = 'senior';
130
+ }
131
+
132
+ return row;
133
+ })
134
+ .getJsonFromCsv('people.csv');
135
+ ```
136
+
137
+ ### Example 3: CSV String with Mapping
138
+
139
+ ```javascript
140
+ const csvString = 'id,name,score\n1,Alice,95\n2,Bob,87\n3,Charlie,92';
141
+
142
+ const result = csvToJson
143
+ .fieldDelimiter(',')
144
+ .mapRows((row) => {
145
+ // Convert score to number and add grade
146
+ const score = parseFloat(row.score);
147
+ row.score = score;
148
+ row.grade = score >= 90 ? 'A' : score >= 80 ? 'B' : 'C';
149
+ return row;
150
+ })
151
+ .csvStringToJson(csvString);
152
+
153
+ // Result:
154
+ // [
155
+ // { id: '1', name: 'Alice', score: 95, grade: 'A' },
156
+ // { id: '2', name: 'Bob', score: 87, grade: 'B' },
157
+ // { id: '3', name: 'Charlie', score: 92, grade: 'A' }
158
+ // ]
159
+ ```
160
+
161
+ ## Chaining
162
+
163
+ The `mapRows()` method is fully chainable with other configuration methods:
164
+
165
+ ```javascript
166
+ const result = csvToJson
167
+ .formatValueByType(true)
168
+ .fieldDelimiter(',')
169
+ .trimHeaderFieldWhiteSpace(true)
170
+ .mapRows(mapper)
171
+ .supportQuotedField(true)
172
+ .getJsonFromCsv('input.csv');
173
+ ```
174
+
175
+ ## Browser Usage
176
+
177
+ The feature is also available in the browser API:
178
+
179
+ ```javascript
180
+ const convert = require('convert-csv-to-json');
181
+
182
+ const mapper = (row, index) => {
183
+ row.processed = true;
184
+ return row;
185
+ };
186
+
187
+ const json = await convert.browser
188
+ .mapRows(mapper)
189
+ .parseFile(fileInputElement.files[0]);
190
+ ```
191
+
192
+ ## Performance Notes
193
+
194
+ - The mapper function is called for each data row (after the header row)
195
+ - Row indices are 0-based and only count data rows (header row is not included)
196
+ - Filtering with `null` returns is more efficient than creating large intermediate arrays if you only need a subset of rows