Improve import resilience with per-message saves and duplicate handling
Save after each message to isolate failures, catch and skip duplicate key violations (SQL error 2601), and clear change tracker on rollback to prevent cascading failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -72,20 +72,32 @@ public class JsonImportService
|
||||
// Upsert Channel
|
||||
await UpsertChannelAsync(export.Channel, export.Guild.Id);
|
||||
|
||||
// Process messages
|
||||
// Process messages - save after each to isolate any issues
|
||||
var processedCount = 0;
|
||||
foreach (var message in export.Messages)
|
||||
{
|
||||
if (await ProcessMessageAsync(message, export.Channel.Id, jsonFilePath, imageRoot))
|
||||
try
|
||||
{
|
||||
processedCount++;
|
||||
if (await ProcessMessageAsync(message, export.Channel.Id, jsonFilePath, imageRoot))
|
||||
{
|
||||
await _context.SaveChangesAsync();
|
||||
processedCount++;
|
||||
}
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is Microsoft.Data.SqlClient.SqlException sqlEx && sqlEx.Number == 2601)
|
||||
{
|
||||
// Duplicate key - log and continue
|
||||
_logger.LogWarning("Duplicate key error for message {MessageId}, skipping: {Error}",
|
||||
message.Id, sqlEx.Message);
|
||||
_context.ChangeTracker.Clear();
|
||||
// Re-upsert guild and channel as they were cleared
|
||||
await UpsertGuildAsync(export.Guild);
|
||||
await UpsertChannelAsync(export.Channel, export.Guild.Id);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("Processed {Count} new messages", processedCount);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Archive the file
|
||||
var archivePath = _archiveService.ArchiveExport(jsonFilePath, archiveRoot);
|
||||
|
||||
@@ -106,6 +118,9 @@ public class JsonImportService
|
||||
catch (Exception ex)
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
_context.ChangeTracker.Clear(); // Clear tracked entities to prevent cascading failures
|
||||
_processedMessages.Clear(); // Clear the session tracking
|
||||
_addedReactions.Clear();
|
||||
_logger.LogError(ex, "Error processing file, rolled back transaction: {Path}", jsonFilePath);
|
||||
throw;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user