or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

errors.mdindex.mdoptions.mdstreaming.mdsync.md
tile.json

errors.mddocs/

Error Handling

CSV Parse provides comprehensive error handling with specific error codes, detailed context information, and flexible error recovery options for robust CSV processing.

Capabilities

CsvError Class

Custom error class extending JavaScript's built-in Error with CSV-specific information and context.

/**
 * Custom error class for CSV parsing errors
 */
class CsvError extends Error {
  /** Specific error code identifying the type of parsing error */
  readonly code: CsvErrorCode;
  
  /** Additional context properties based on error type */
  [key: string]: any;
  
  /**
   * Creates a new CSV parsing error
   * @param code - Specific error code
   * @param message - Error message or array of message parts
   * @param options - Parser options for context
   * @param contexts - Additional context objects
   */
  constructor(
    code: CsvErrorCode,
    message: string | string[],
    options?: OptionsNormalized,
    ...contexts: unknown[]
  );
}

Usage Examples:

import { parse, CsvError } from "csv-parse";

try {
  parse("invalid,csv,data\nwith,inconsistent", {
    columns: true,
    relax_column_count: false
  });
} catch (err) {
  if (err instanceof CsvError) {
    console.error("CSV Error Code:", err.code);
    console.error("Message:", err.message);
    console.error("Line:", err.lines);
    console.error("Column:", err.column);
    console.error("Raw record:", err.raw);
  }
}

// Error context extraction
function handleCsvError(error) {
  if (error instanceof CsvError) {
    const context = {
      code: error.code,
      message: error.message,
      line: error.lines || 'unknown',
      column: error.column || 'unknown',
      rawData: error.raw || 'unavailable'
    };
    
    console.error("CSV parsing failed:", context);
    return context;
  }
  throw error; // Re-throw non-CSV errors
}

Error Codes

Comprehensive set of error codes identifying specific parsing issues.

type CsvErrorCode = 
  // Argument and validation errors
  | "CSV_INVALID_ARGUMENT"
  | "CSV_INVALID_COLUMN_DEFINITION"
  | "CSV_INVALID_COLUMN_MAPPING"
  
  // Option validation errors
  | "CSV_INVALID_OPTION_BOM"
  | "CSV_INVALID_OPTION_CAST"
  | "CSV_INVALID_OPTION_CAST_DATE"
  | "CSV_INVALID_OPTION_COLUMNS"
  | "CSV_INVALID_OPTION_COMMENT"
  | "CSV_INVALID_OPTION_DELIMITER"
  | "CSV_INVALID_OPTION_GROUP_COLUMNS_BY_NAME"
  | "CSV_INVALID_OPTION_ON_RECORD"
  
  // Parsing format errors
  | "CSV_INVALID_CLOSING_QUOTE"
  | "CSV_QUOTE_NOT_CLOSED"
  | "INVALID_OPENING_QUOTE"
  | "CSV_NON_TRIMABLE_CHAR_AFTER_CLOSING_QUOTE"
  
  // Record structure errors
  | "CSV_RECORD_INCONSISTENT_FIELDS_LENGTH"
  | "CSV_RECORD_INCONSISTENT_COLUMNS"
  | "CSV_OPTION_COLUMNS_MISSING_NAME"
  
  // Resource and limit errors
  | "CSV_MAX_RECORD_SIZE"
  
  // General errors
  | "CSV_UNKNOWN_ERROR";

Usage Examples:

import { parse, CsvError } from "csv-parse";

// Handle specific error types
try {
  parse(data, options);
} catch (err) {
  if (err instanceof CsvError) {
    switch (err.code) {
      case "CSV_INVALID_CLOSING_QUOTE":
        console.error("Quote not properly closed at line", err.lines);
        break;
        
      case "CSV_RECORD_INCONSISTENT_FIELDS_LENGTH":
        console.error("Inconsistent column count at line", err.lines);
        console.error("Expected", err.expectedColumns, "but got", err.actualColumns);
        break;
        
      case "CSV_MAX_RECORD_SIZE":
        console.error("Record too large at line", err.lines);
        console.error("Maximum size:", err.maxSize, "bytes");
        break;
        
      case "CSV_INVALID_OPTION_DELIMITER":
        console.error("Invalid delimiter configuration:", err.delimiter);
        break;
        
      default:
        console.error("Unknown CSV error:", err.code, err.message);
    }
  }
}

Error Recovery Strategies

Options and patterns for handling and recovering from parsing errors.

Usage Examples:

import { parse } from "csv-parse";

// Skip invalid records and continue processing
const parser = parse({
  columns: true,
  skip_records_with_error: true,
  relax_column_count: true,
  on_skip: (err, rawRecord) => {
    // Log skipped records for later analysis
    console.warn(`Skipped record at line ${err?.lines || 'unknown'}: ${rawRecord}`);
    console.warn(`Reason: ${err?.message || 'unknown error'}`);
    
    // Optionally store for later processing
    skippedRecords.push({
      line: err?.lines,
      raw: rawRecord,
      error: err?.code,
      message: err?.message
    });
  }
});

// Collect parsing statistics
let totalRecords = 0;
let errorCount = 0;
const skippedRecords = [];

parser.on('data', (record) => {
  totalRecords++;
});

parser.on('end', () => {
  console.log(`Processing complete:`);
  console.log(`- Total records: ${totalRecords}`);
  console.log(`- Skipped records: ${skippedRecords.length}`);
  console.log(`- Success rate: ${((totalRecords / (totalRecords + skippedRecords.length)) * 100).toFixed(2)}%`);
});

Validation and Prevention

Proactive error prevention through validation and safe parsing practices.

Usage Examples:

import { parse, CsvError } from "csv-parse";

// Validate options before parsing
function validateCsvOptions(options) {
  try {
    // Test with minimal data to validate options
    parse("test", options);
    return { valid: true };
  } catch (err) {
    if (err instanceof CsvError && err.code.startsWith('CSV_INVALID_OPTION')) {
      return { 
        valid: false, 
        error: err.code, 
        message: err.message 
      };
    }
    return { valid: true }; // Other errors are not option-related
  }
}

// Safe parsing wrapper
async function safeCsvParse(data, options = {}) {
  const safeOptions = {
    // Default safe options
    skip_records_with_error: true,
    relax_column_count: true,
    relax_quotes: true,
    skip_empty_lines: true,
    max_record_size: 1024 * 1024, // 1MB limit
    ...options
  };
  
  const results = {
    records: [],
    errors: [],
    stats: {
      totalLines: 0,
      validRecords: 0,
      skippedRecords: 0
    }
  };
  
  try {
    const parser = parse(safeOptions);
    
    parser.on('data', (record) => {
      results.records.push(record);
      results.stats.validRecords++;
    });
    
    parser.on('skip', (err, rawRecord) => {
      results.errors.push({
        code: err?.code,
        message: err?.message,
        line: err?.lines,
        raw: rawRecord
      });
      results.stats.skippedRecords++;
    });
    
    parser.on('end', () => {
      results.stats.totalLines = parser.info.lines;
    });
    
    parser.write(data);
    parser.end();
    
    return results;
  } catch (err) {
    throw new Error(`Fatal CSV parsing error: ${err.message}`);
  }
}

// Usage
try {
  const result = await safeCsvParse(csvData, { columns: true });
  console.log(`Parsed ${result.stats.validRecords} records`);
  if (result.errors.length > 0) {
    console.warn(`${result.errors.length} records had errors`);
  }
} catch (err) {
  console.error("Failed to parse CSV:", err.message);
}

Debugging and Diagnostics

Tools and techniques for debugging CSV parsing issues.

Usage Examples:

import { parse, CsvError } from "csv-parse";

// Enhanced error reporting
function debugCsvParsing(data, options = {}) {
  const debugOptions = {
    ...options,
    info: true,  // Include parsing info
    raw: true,   // Include raw data
    skip_records_with_error: true
  };
  
  const parser = parse(debugOptions);
  const diagnostics = {
    errors: [],
    warnings: [],
    records: []
  };
  
  parser.on('data', (record) => {
    diagnostics.records.push({
      line: record.info.lines,
      data: record.record,
      raw: record.raw
    });
  });
  
  parser.on('skip', (err, rawRecord) => {
    diagnostics.errors.push({
      line: err?.lines || 'unknown',
      code: err?.code,
      message: err?.message,
      raw: rawRecord,
      context: {
        column: err?.column,
        quoting: err?.quoting,
        escape: err?.escape
      }
    });
  });
  
  parser.on('end', () => {
    const info = parser.info;
    console.log('Parsing Diagnostics:', {
      totalLines: info.lines,
      totalRecords: info.records,
      commentLines: info.comment_lines,
      emptyLines: info.empty_lines,
      bytesProcessed: info.bytes,
      invalidFieldLength: info.invalid_field_length,
      errors: diagnostics.errors.length,
      successRate: `${((info.records / info.lines) * 100).toFixed(2)}%`
    });
    
    if (diagnostics.errors.length > 0) {
      console.log('Error Details:');
      diagnostics.errors.forEach((error, index) => {
        console.log(`  ${index + 1}. Line ${error.line}: ${error.code} - ${error.message}`);
        console.log(`     Raw: ${error.raw}`);
      });
    }
  });
  
  parser.write(data);
  parser.end();
  
  return diagnostics;
}

// Error pattern analysis
function analyzeCsvErrors(csvData, options) {
  const errorPatterns = new Map();
  
  parse(csvData, {
    ...options,
    skip_records_with_error: true,
    on_skip: (err, rawRecord) => {
      const pattern = err?.code || 'UNKNOWN';
      if (!errorPatterns.has(pattern)) {
        errorPatterns.set(pattern, {
          count: 0,
          examples: []
        });
      }
      
      const patternData = errorPatterns.get(pattern);
      patternData.count++;
      
      if (patternData.examples.length < 3) {
        patternData.examples.push({
          line: err?.lines,
          raw: rawRecord,
          message: err?.message
        });
      }
    }
  });
  
  console.log('Error Pattern Analysis:');
  errorPatterns.forEach((data, pattern) => {
    console.log(`  ${pattern}: ${data.count} occurrences`);
    data.examples.forEach((example, i) => {
      console.log(`    Example ${i + 1}: Line ${example.line} - ${example.raw}`);
    });
  });
}