Skip to content

Commit 35b360f

Browse files
Copilotrajbos
andcommitted
Fix CSV header validation whitespace handling and improve error reporting
Co-authored-by: rajbos <6085745+rajbos@users.noreply.github.com>
1 parent 19a6579 commit 35b360f

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

src/App.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,13 @@ function App() {
8181

8282
toast.success(`Loaded ${parsedData.length} records successfully`);
8383
} catch (error) {
84-
console.error("Error parsing CSV:", error);
84+
// Provide user-friendly error messages
8585
let errorMessage = "Failed to parse CSV file. Please check the format.";
8686

8787
if (error instanceof Error) {
88+
// Log detailed error information to console for debugging
89+
console.error("CSV parsing error details:", error);
90+
8891
// Provide more specific error messages based on the error type
8992
if (error.message.includes("missing required columns")) {
9093
errorMessage = "Invalid CSV format: " + error.message;

src/lib/utils.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,30 @@ export function parseCSV(csv: string): CopilotUsageData[] {
4141
m.endsWith(',')
4242
? m.slice(0, -1).replace(/^"(.*)"$/, '$1')
4343
: m.replace(/^"(.*)"$/, '$1')
44-
);
44+
).filter(h => h.trim() !== '').map(h => h.trim()); // Filter empty strings and trim whitespace
4545

4646
// Check if all expected headers are present (case-insensitive exact match)
4747
const missingHeaders = expectedHeaders.filter(expected =>
4848
!headers.some(header => header.toLowerCase() === expected.toLowerCase())
4949
);
5050

51+
// Log detailed header information for debugging
52+
if (missingHeaders.length > 0) {
53+
console.log('CSV Header validation failed:');
54+
console.log('Expected headers:', expectedHeaders);
55+
console.log('Found headers:', headers);
56+
console.log('Missing headers:', missingHeaders);
57+
headers.forEach((header, i) => {
58+
const expectedHeader = expectedHeaders[i];
59+
if (expectedHeader) {
60+
const matches = header.toLowerCase() === expectedHeader.toLowerCase();
61+
console.log(` Column ${i + 1}: "${header}" ${matches ? '✅' : '❌'} (expected: "${expectedHeader}")`);
62+
} else {
63+
console.log(` Column ${i + 1}: "${header}" (extra column)`);
64+
}
65+
});
66+
}
67+
5168
if (missingHeaders.length > 0) {
5269
throw new Error(`CSV is missing required columns: ${missingHeaders.join(', ')}. Expected columns: ${expectedHeaders.join(', ')}`);
5370
}

src/test/csv-header-validation.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,24 @@ user1,2024-01-01T00:00:00Z,gpt-4,100,1.5,false`
6868
expect(() => parseCSV(csvMixedCase)).not.toThrow()
6969
})
7070

71+
it('should handle CSV with whitespace in headers', () => {
72+
const csvWithWhitespace = `" Timestamp "," User "," Model "," Requests Used "," Exceeds Monthly Quota "," Total Monthly Quota "
73+
2024-01-01T00:00:00Z,user1,gpt-4,1.5,false,100`
74+
75+
expect(() => parseCSV(csvWithWhitespace)).not.toThrow()
76+
77+
const result = parseCSV(csvWithWhitespace)
78+
expect(result).toHaveLength(1)
79+
expect(result[0]).toEqual({
80+
timestamp: new Date('2024-01-01T00:00:00Z'),
81+
user: 'user1',
82+
model: 'gpt-4',
83+
requestsUsed: 1.5,
84+
exceedsQuota: false,
85+
totalMonthlyQuota: '100'
86+
})
87+
})
88+
7189
it('should validate data types correctly with valid headers', () => {
7290
const validCsv = `"Timestamp","User","Model","Requests Used","Exceeds Monthly Quota","Total Monthly Quota"
7391
2024-01-01T00:00:00Z,user1,gpt-4,1.5,false,100`

0 commit comments

Comments
 (0)