mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-28 21:40:58 +01:00
feat(upgrades): enhance upgrade manager with detailed notifications for success and failure
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { logger } from '$logger/logger.ts';
|
||||
import { runUpgradeManager } from '../logic/upgradeManager.ts';
|
||||
import { notificationManager } from '$notifications/NotificationManager.ts';
|
||||
import type { JobDefinition, JobResult } from '../types.ts';
|
||||
|
||||
/**
|
||||
@@ -52,6 +53,65 @@ export const upgradeManagerJob: JobDefinition = {
|
||||
}
|
||||
}
|
||||
|
||||
// Send notification summary (only if something was processed, excluding skipped)
|
||||
const processedCount = result.successCount + result.failureCount;
|
||||
if (processedCount > 0) {
|
||||
const successfulInstances = result.instances.filter((i) => i.success);
|
||||
const failedInstances = result.instances.filter((i) => !i.success && i.error && !i.error.includes('disabled') && !i.error.includes('not yet supported'));
|
||||
const hasDryRun = result.instances.some((i) => i.dryRun);
|
||||
|
||||
// Build message lines for each successful instance
|
||||
const messageLines: string[] = [];
|
||||
for (const inst of successfulInstances) {
|
||||
const dryRunLabel = inst.dryRun ? ' [DRY RUN]' : '';
|
||||
messageLines.push(`**${inst.instanceName}: ${inst.filterName}${dryRunLabel}**`);
|
||||
messageLines.push(`Filter: ${inst.matchedCount} matched → ${inst.afterCooldown} after cooldown`);
|
||||
messageLines.push(`Selection: ${inst.itemsSearched}/${inst.itemsRequested} items`);
|
||||
if (inst.items && inst.items.length > 0) {
|
||||
messageLines.push(`Items: ${inst.items.join(', ')}`);
|
||||
}
|
||||
messageLines.push('');
|
||||
}
|
||||
|
||||
// Add failed instances
|
||||
for (const inst of failedInstances) {
|
||||
messageLines.push(`**${inst.instanceName}: Failed**`);
|
||||
messageLines.push(`Error: ${inst.error}`);
|
||||
messageLines.push('');
|
||||
}
|
||||
|
||||
let notificationType: string;
|
||||
let title: string;
|
||||
|
||||
if (result.failureCount === 0) {
|
||||
notificationType = 'upgrade.success';
|
||||
title = hasDryRun ? 'Upgrade Completed (Dry Run)' : 'Upgrade Completed';
|
||||
} else if (result.successCount === 0) {
|
||||
notificationType = 'upgrade.failed';
|
||||
title = 'Upgrade Failed';
|
||||
} else {
|
||||
notificationType = 'upgrade.partial';
|
||||
title = 'Upgrade Partially Completed';
|
||||
}
|
||||
|
||||
await notificationManager.notify({
|
||||
type: notificationType,
|
||||
title,
|
||||
message: messageLines.join('\n').trim(),
|
||||
metadata: {
|
||||
successCount: result.successCount,
|
||||
failureCount: result.failureCount,
|
||||
dryRun: hasDryRun,
|
||||
instances: result.instances.filter((i) => i.success).map((i) => ({
|
||||
name: i.instanceName,
|
||||
filter: i.filterName,
|
||||
searched: i.itemsSearched,
|
||||
items: i.items
|
||||
}))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Consider job failed only if all configs failed
|
||||
if (result.failureCount > 0 && result.successCount === 0) {
|
||||
return {
|
||||
@@ -65,14 +125,23 @@ export const upgradeManagerJob: JobDefinition = {
|
||||
output: message
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
|
||||
await logger.error('Upgrade manager job failed', {
|
||||
source: 'UpgradeManagerJob',
|
||||
meta: { error: error instanceof Error ? error.message : String(error) }
|
||||
meta: { error: errorMessage }
|
||||
});
|
||||
|
||||
await notificationManager.notify({
|
||||
type: 'upgrade.failed',
|
||||
title: 'Upgrade Failed',
|
||||
message: `Upgrade manager encountered an error: ${errorMessage}`,
|
||||
metadata: { error: errorMessage }
|
||||
});
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
error: errorMessage
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@ export interface UpgradeInstanceStatus {
|
||||
success: boolean;
|
||||
filterName?: string;
|
||||
itemsSearched?: number;
|
||||
itemsRequested?: number;
|
||||
matchedCount?: number;
|
||||
afterCooldown?: number;
|
||||
items?: string[];
|
||||
dryRun?: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
@@ -79,6 +84,11 @@ async function processConfig(config: UpgradeConfig): Promise<UpgradeInstanceStat
|
||||
success: log.status === 'success' || log.status === 'partial',
|
||||
filterName: log.config.selectedFilter,
|
||||
itemsSearched: log.selection.actualCount,
|
||||
itemsRequested: log.selection.requestedCount,
|
||||
matchedCount: log.filter.matchedCount,
|
||||
afterCooldown: log.filter.afterCooldown,
|
||||
items: log.selection.items.map((i) => i.title),
|
||||
dryRun: config.dryRun,
|
||||
error: log.status === 'failed' ? log.results.errors.join('; ') : undefined
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@@ -84,6 +84,26 @@ export const notificationTypes: NotificationType[] = [
|
||||
label: 'Database Sync (Failed)',
|
||||
category: 'Databases',
|
||||
description: 'Notification when database sync fails'
|
||||
},
|
||||
|
||||
// Upgrades
|
||||
{
|
||||
id: 'upgrade.success',
|
||||
label: 'Upgrade Completed (Success)',
|
||||
category: 'Upgrades',
|
||||
description: 'Notification when all upgrade searches complete successfully'
|
||||
},
|
||||
{
|
||||
id: 'upgrade.partial',
|
||||
label: 'Upgrade Completed (Partial)',
|
||||
category: 'Upgrades',
|
||||
description: 'Notification when some upgrade searches succeed and some fail'
|
||||
},
|
||||
{
|
||||
id: 'upgrade.failed',
|
||||
label: 'Upgrade Failed',
|
||||
category: 'Upgrades',
|
||||
description: 'Notification when all upgrade searches fail'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { Actions, ServerLoad } from '@sveltejs/kit';
|
||||
import { arrInstancesQueries } from '$db/queries/arrInstances.ts';
|
||||
import { upgradeConfigsQueries } from '$db/queries/upgradeConfigs.ts';
|
||||
import { logger } from '$logger/logger.ts';
|
||||
import { notificationManager } from '$notifications/NotificationManager.ts';
|
||||
import type { FilterConfig, FilterMode } from '$lib/shared/filters.ts';
|
||||
import { processUpgradeConfig } from '$lib/server/upgrades/processor.ts';
|
||||
|
||||
@@ -221,6 +222,31 @@ export const actions: Actions = {
|
||||
upgradeConfigsQueries.incrementFilterIndex(id);
|
||||
}
|
||||
|
||||
// Send notification
|
||||
const isSuccess = result.status === 'success' || result.status === 'partial';
|
||||
const dryRunLabel = result.config.dryRun ? ' [DRY RUN]' : '';
|
||||
const itemsList = result.selection.items.map((i) => i.title).join(', ');
|
||||
|
||||
await notificationManager.notify({
|
||||
type: isSuccess ? 'upgrade.success' : 'upgrade.failed',
|
||||
title: `${instance.name}: ${result.config.selectedFilter}${dryRunLabel}`,
|
||||
message: [
|
||||
`Filter: ${result.filter.matchedCount} matched → ${result.filter.afterCooldown} after cooldown`,
|
||||
`Selection: ${result.selection.actualCount}/${result.selection.requestedCount} items`,
|
||||
`Results: ${result.results.searchesTriggered} searches, ${result.results.successful} successful`,
|
||||
itemsList ? `Items: ${itemsList}` : null
|
||||
].filter(Boolean).join('\n'),
|
||||
metadata: {
|
||||
instanceId: id,
|
||||
instanceName: instance.name,
|
||||
filterName: result.config.selectedFilter,
|
||||
itemsSearched: result.selection.actualCount,
|
||||
matchedCount: result.filter.matchedCount,
|
||||
dryRun: result.config.dryRun,
|
||||
items: result.selection.items.map((i) => i.title)
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
runResult: {
|
||||
@@ -234,10 +260,25 @@ export const actions: Actions = {
|
||||
}
|
||||
};
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
||||
|
||||
await logger.error('Manual upgrade run failed', {
|
||||
source: 'upgrades',
|
||||
meta: { instanceId: id, error: err }
|
||||
});
|
||||
|
||||
await notificationManager.notify({
|
||||
type: 'upgrade.failed',
|
||||
title: 'Upgrade Failed',
|
||||
message: `${instance.name}: ${errorMessage}`,
|
||||
metadata: {
|
||||
instanceId: id,
|
||||
instanceName: instance.name,
|
||||
error: errorMessage,
|
||||
dryRun: true
|
||||
}
|
||||
});
|
||||
|
||||
return fail(500, { error: 'Upgrade run failed. Check logs for details.' });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user