6.5 KiB
6.5 KiB
CSV Import Error Handling Improvements
Problem Solved
Original Issue: When importing CSV files, if a single record had a database constraint violation (like duplicate SKU or email), the entire import would crash with a database exception, providing a poor user experience.
Solution Applied
All three CSV import methods now use robust error handling that:
- ✅ Validates all records in-memory first
- ✅ Saves records one-by-one to isolate failures
- ✅ Catches database exceptions gracefully
- ✅ Skips problem records and continues importing
- ✅ Provides detailed error/warning messages
Changes Made
1. Updated Sample Data Files
- inventory-items-sample.csv: Changed SKU prefix from
PWD-*/CON-*toIMP-PWD-*/IMP-CON-*- Prevents conflicts with seed data
- Also created
inventory-items-sample-v2.csvas backup
2. Enhanced Import Service (CsvImportService.cs)
All Three Import Methods Now:
Customer Import (ImportCustomersAsync):
- Detects duplicate emails in database and within CSV file
- Saves each customer individually
- Catches database constraint violations
- Reports: "Row X: Customer with email 'Y' already exists in database. Skipping."
Catalog Items Import (ImportCatalogItemsAsync):
- Detects duplicate SKUs in database and within CSV file
- Saves each catalog item individually
- Catches database constraint violations
- Reports: "Row X: Catalog item with SKU 'Y' already exists in database. Skipping."
Inventory Import (ImportInventoryItemsAsync):
- Detects duplicate SKUs in database and within CSV file
- Saves each inventory item individually
- Catches database constraint violations
- Reports: "Row X: SKU 'Y' already exists in database. Skipping."
3. Updated Documentation
- README.md: Added troubleshooting section for duplicate SKU/email errors
- Explains how to handle conflicts (use new sample files, delete existing data, or edit CSV)
How It Works Now
Before (Old Behavior):
1. Read CSV file
2. Validate all rows
3. Add all rows to DbContext
4. Call SaveChanges() once
5. ❌ If ANY row fails → entire import crashes with exception
After (New Behavior):
1. Read CSV file
2. Validate all rows (in-memory duplicate detection)
3. Build list of valid items to import
4. Loop through each item:
a. Add to DbContext
b. Call SaveChanges()
c. If success → increment success count
d. If database error → log warning, rollback, continue to next
5. ✅ Return detailed results: X succeeded, Y failed
Error Messages You'll See
Duplicate Detection (In-Memory):
- ✅
Row 5: Customer with email 'john@example.com' already exists in database. Skipping. - ✅
Row 12: Duplicate SKU 'IMP-PWD-BLK-001' found in import file. Skipping.
Database Constraint Violations:
- ✅
Row 8: SKU 'PWD-BLK-001' already exists in database (detected during save). Skipping. - ✅
Row 15: Database error - Cannot insert duplicate key...
Missing Required Fields:
- ✅
Row 3: SKU is required. - ✅
Row 7: CompanyName is required.
Warnings (Non-Critical):
- ⚠️
Row 10: Pricing tier 'DIAMOND' not found. Customer will have no pricing tier. - ⚠️
Row 22: Category 'Automotive/Wheels' created automatically.
Example Import Results
Import Results:
✅ Success: 18 records imported
❌ Errors: 2 records skipped
Warnings:
- Row 5: Customer with email 'jane@acme.com' already exists in database. Skipping.
- Row 12: Pricing tier 'GOLD' not found. Customer will have no pricing tier.
Errors:
- Row 8: SKU is required.
- Row 15: Duplicate SKU 'IMP-PWD-BLK-001' found in import file. Skipping.
Testing the Fix
Test Case 1: Import with Existing Data
- Run Platform Management > Seed Data to create demo inventory
- Try to import
inventory-items-sample-v2.csv(old SKU format) - ✅ Expected: Graceful warnings, no crash, other records still import
Test Case 2: Import Fresh Data
- Use the updated
inventory-items-sample.csv(IMP- prefix) - Upload to Tools > CSV Bulk Import > Inventory tab
- ✅ Expected: All 25 records import successfully
Test Case 3: Duplicate Within CSV
- Edit any CSV file and duplicate a row (same SKU or email)
- Upload the file
- ✅ Expected: First occurrence imports, second gets warning "found in import file"
Test Case 4: Invalid Data
- Edit CSV and remove required field (SKU, CompanyName, etc.)
- Upload the file
- ✅ Expected: Row skipped with clear error, other rows still import
Benefits
- No More Crashes: Database exceptions don't crash the import
- Partial Imports Work: 18 out of 20 records? No problem!
- Clear Feedback: Know exactly which rows failed and why
- Data Integrity: Transaction rollback prevents partial saves
- User-Friendly: Non-technical users can understand error messages
Technical Details
Transaction Handling
Each record is saved in its own mini-transaction:
try
{
await _unitOfWork.InventoryItems.AddAsync(item);
await _unitOfWork.CompleteAsync(); // Commit this one record
result.SuccessCount++;
}
catch (DbUpdateException dbEx)
{
result.Warnings.Add($"Row {rowNumber}: SKU already exists. Skipping.");
await uow.RollbackTransactionAsync(); // Rollback just this record
// Continue to next record
}
Duplicate Detection Strategy
- First Pass (In-Memory): Check against existing database data (fast)
- Second Pass (In-Memory): Check for duplicates within the CSV file itself
- Third Pass (Database): Catch any race conditions or concurrent inserts
Files Modified
- ✅
PowderCoating.Infrastructure/Services/CsvImportService.cs(3 methods updated) - ✅
sample-data/inventory-items-sample.csv(SKUs updated) - ✅
sample-data/inventory-items-sample-v2.csv(created) - ✅
sample-data/README.md(troubleshooting added) - ✅
sample-data/IMPORT_ERROR_FIXES.md(this file)
Build Status
✅ Build Succeeded - 0 Errors, 0 New Warnings
Next Steps
- Test the imports with the updated sample CSV files
- Re-import inventory using the new
inventory-items-sample.csv(IMP- prefix) - Delete old inventory items if you have duplicates from seed data (optional)
- Create your own CSV files using the updated template format
Questions?
- Sample files not importing? Check the README.md troubleshooting section
- Still seeing errors? The error messages now tell you exactly what's wrong
- Want to reset data? Delete existing records or use new SKU prefixes in your CSV