fix: use in-memory startedAt for cron job log to survive DB restore
The auto-import wipes the database, destroying the cronJobLog record created at the start of the job. Now duration is calculated from a local variable instead of querying the DB, and if the record is gone a fresh log entry is created in the restored database. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -79,12 +79,12 @@ export const startBackupCron = () => {
|
||||
pruneOldBackups(LOCAL_BACKUP_DIR);
|
||||
await storage.createBackup(admin.id);
|
||||
await storage.deleteNotificationsByType(admin.id, "BACKUP");
|
||||
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "success", new Date());
|
||||
console.log(`✅ Local backup done → ${filename}`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("Local backup failed:", err);
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "failed", new Date(), errorMessage);
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
@@ -113,7 +113,7 @@ export const startBackupCron = () => {
|
||||
const destination = await storage.getActiveBackupDestination(admin.id);
|
||||
if (!destination) {
|
||||
const errorMessage = "No backup destination configured.";
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "failed", new Date(), errorMessage);
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
@@ -124,7 +124,7 @@ export const startBackupCron = () => {
|
||||
|
||||
if (!fs.existsSync(destination.path)) {
|
||||
const errorMessage = "Backup destination drive not found or disconnected.";
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "failed", new Date(), errorMessage);
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
@@ -145,12 +145,12 @@ export const startBackupCron = () => {
|
||||
pruneOldBackups(usbBackupPath);
|
||||
await storage.createBackup(admin.id);
|
||||
await storage.deleteNotificationsByType(admin.id, "BACKUP");
|
||||
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "success", new Date());
|
||||
console.log(`✅ USB backup done → ${usbBackupPath}/${filename}`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("USB backup failed:", err);
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "failed", new Date(), errorMessage);
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
@@ -178,13 +178,13 @@ export const startBackupCron = () => {
|
||||
try {
|
||||
await runRclonePull();
|
||||
writeRcloneConfig({ lastSyncAt: new Date().toISOString(), lastSyncStatus: "success", lastSyncError: null });
|
||||
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "success", new Date());
|
||||
console.log(`Rclone backup complete.`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("Rclone backup failed:", err);
|
||||
writeRcloneConfig({ lastSyncAt: new Date().toISOString(), lastSyncStatus: "failed", lastSyncError: errorMessage });
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "failed", new Date(), errorMessage);
|
||||
if (admin) {
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
@@ -214,13 +214,13 @@ export const startBackupCron = () => {
|
||||
try {
|
||||
await importLatestBackup();
|
||||
writeRcloneConfig({ lastImportAt: new Date().toISOString(), lastImportStatus: "success", lastImportError: null });
|
||||
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "success", new Date());
|
||||
console.log(`Auto-import complete.`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("Auto-import failed:", err);
|
||||
writeRcloneConfig({ lastImportAt: new Date().toISOString(), lastImportStatus: "failed", lastImportError: errorMessage });
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "failed", new Date(), errorMessage);
|
||||
if (admin) {
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
@@ -251,13 +251,13 @@ export const startBackupCron = () => {
|
||||
await runNetworkSync(config.sourceUrl, config.apiKey);
|
||||
await runNetworkFilesSync(config.sourceUrl, config.apiKey);
|
||||
writeSyncConfig({ lastSyncAt: new Date().toISOString(), lastSyncStatus: "success", lastSyncError: null });
|
||||
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "success", new Date());
|
||||
console.log(`✅ Network sync complete (database + uploads).`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("Network sync failed:", err);
|
||||
writeSyncConfig({ lastSyncAt: new Date().toISOString(), lastSyncStatus: "failed", lastSyncError: errorMessage });
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await cronJobLogStorage.completeJobLog(log.id, log.jobName, startedAt, "failed", new Date(), errorMessage);
|
||||
if (admin) {
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
|
||||
@@ -24,14 +24,22 @@ export const cronJobLogStorage = {
|
||||
|
||||
async completeJobLog(
|
||||
id: number,
|
||||
jobName: string,
|
||||
startedAt: Date,
|
||||
status: CronJobStatus,
|
||||
completedAt: Date,
|
||||
errorMessage?: string
|
||||
): Promise<CronJobLogEntry> {
|
||||
const durationMs = completedAt.getTime() - (await db.cronJobLog.findUniqueOrThrow({ where: { id } })).startedAt.getTime();
|
||||
return db.cronJobLog.update({
|
||||
where: { id },
|
||||
data: { status, completedAt, durationMs, errorMessage: errorMessage ?? null },
|
||||
const durationMs = completedAt.getTime() - startedAt.getTime();
|
||||
const existing = await db.cronJobLog.findUnique({ where: { id } });
|
||||
if (existing) {
|
||||
return db.cronJobLog.update({
|
||||
where: { id },
|
||||
data: { status, completedAt, durationMs, errorMessage: errorMessage ?? null },
|
||||
});
|
||||
}
|
||||
return db.cronJobLog.create({
|
||||
data: { jobName, status, startedAt, completedAt, durationMs, errorMessage: errorMessage ?? null },
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user