Skip to content

Commit 42dd8e2

Browse files
fix(tables): guard date coercion against out-of-range values
1 parent 4f72933 commit 42dd8e2

2 files changed

Lines changed: 23 additions & 5 deletions

File tree

apps/sim/lib/table/__tests__/validation.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,20 @@ describe('Validation', () => {
343343
expect(data.created).toBe(date.toISOString())
344344
})
345345

346+
it('nulls an out-of-range epoch number for an optional date column without throwing', () => {
347+
const data = { name: 'Acme', founded: 2000, created: 1e20 }
348+
const result = coerceRowToSchema(data, schema)
349+
expect(result.valid).toBe(true)
350+
expect(data.created).toBeNull()
351+
})
352+
353+
it('nulls an invalid Date instance for an optional date column without throwing', () => {
354+
const data = { name: 'Acme', founded: 2000, created: new Date('not-a-date') }
355+
const result = coerceRowToSchema(data, schema)
356+
expect(result.valid).toBe(true)
357+
expect(data.created).toBeNull()
358+
})
359+
346360
it('leaves already-correct values untouched and passes through json', () => {
347361
const data = { name: 'Acme', founded: 2000, metadata: { k: 'v' } }
348362
const result = coerceRowToSchema(data, schema)

apps/sim/lib/table/validation.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -289,13 +289,17 @@ function coerceValueToColumnType(
289289
if (normalized === 'false') return { ok: true, value: false }
290290
}
291291
return { ok: false }
292-
case 'date':
293-
if (value instanceof Date) return { ok: true, value: value.toISOString() }
292+
case 'date': {
294293
if (typeof value === 'string' && !Number.isNaN(Date.parse(value))) return { ok: true, value }
295-
if (typeof value === 'number' && Number.isFinite(value)) {
296-
return { ok: true, value: new Date(value).toISOString() }
297-
}
294+
// Date instances and epoch numbers may still be out of the representable
295+
// range (>±8.64e15ms) — guard `toISOString()`, which throws RangeError on
296+
// an Invalid Date, so an over-range value degrades to `{ ok: false }`
297+
// rather than crashing the write.
298+
const date =
299+
value instanceof Date ? value : typeof value === 'number' ? new Date(value) : null
300+
if (date && !Number.isNaN(date.getTime())) return { ok: true, value: date.toISOString() }
298301
return { ok: false }
302+
}
299303
default:
300304
return { ok: true, value }
301305
}

0 commit comments

Comments
 (0)