Skip to content

Commit 52dd4ca

Browse files
fix(tables): log rollback failures and surface a clear reason on failed CSV import
1 parent 96b203a commit 52dd4ca

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

apps/sim/lib/copilot/tools/server/table/user-table.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ describe('userTableServerTool.create_from_file', () => {
249249
mockDownloadWorkspaceFile.mockResolvedValue(Buffer.from('name,age\nAlice,30\nBob,40'))
250250
mockGetWorkspaceTableLimits.mockResolvedValue({ maxRowsPerTable: 1000, maxTables: 3 })
251251
mockCreateTable.mockResolvedValue(buildTable({ id: 'tbl_new', name: 'people' }))
252+
mockDeleteTable.mockResolvedValue(undefined)
252253
mockBatchInsertRows.mockImplementation(async (data: { rows: unknown[] }) =>
253254
data.rows.map((_, i) => ({ id: `row_${i}` }))
254255
)
@@ -286,8 +287,8 @@ describe('userTableServerTool.create_from_file', () => {
286287
expect(mockDeleteTable).not.toHaveBeenCalled()
287288
})
288289

289-
it('deletes the created table when row insertion fails', async () => {
290-
mockBatchInsertRows.mockRejectedValueOnce(new Error('Maximum row limit (1000) reached'))
290+
it('rolls back the created table and reports the reason when row insertion fails', async () => {
291+
mockBatchInsertRows.mockRejectedValueOnce(new Error('Row 2: Column "email" must be unique'))
291292

292293
const result = await userTableServerTool.execute(
293294
{ operation: 'create_from_file', args: { fileId: 'file-1' } },
@@ -296,6 +297,8 @@ describe('userTableServerTool.create_from_file', () => {
296297

297298
expect(result.success).toBe(false)
298299
expect(mockDeleteTable).toHaveBeenCalledWith('tbl_new', expect.any(String))
300+
expect(result.message).toMatch(/rolled back/i)
301+
expect(result.message).toMatch(/must be unique/i)
299302
})
300303
})
301304

apps/sim/lib/copilot/tools/server/table/user-table.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,8 +788,28 @@ export const userTableServerTool: BaseServerTool<UserTableArgs, UserTableResult>
788788
try {
789789
inserted = await batchInsertAll(table.id, coerced, table, workspaceId, context)
790790
} catch (insertError) {
791-
await deleteTable(table.id, requestId).catch(() => {})
792-
throw insertError
791+
const cleanupRequestId = generateId().slice(0, 8)
792+
await deleteTable(table.id, cleanupRequestId).catch((cleanupError) => {
793+
logger.error('Failed to roll back table after import failure', {
794+
tableId: table.id,
795+
error: toError(cleanupError).message,
796+
})
797+
})
798+
const reason = toError(insertError).message
799+
const cause =
800+
insertError instanceof Error && insertError.cause
801+
? toError(insertError.cause).message
802+
: undefined
803+
logger.error('Failed to import rows into new table', {
804+
tableId: table.id,
805+
fileName: file.name,
806+
error: reason,
807+
cause,
808+
})
809+
return {
810+
success: false,
811+
message: `Failed to import rows from "${file.name}" — the table was rolled back. ${cause ? `${reason} (${cause})` : reason}`,
812+
}
793813
}
794814

795815
logger.info('Table created from file', {

0 commit comments

Comments
 (0)