diff --git a/Data_Coupler/BackgroundServices/ScheduledJobService.cs b/Data_Coupler/BackgroundServices/ScheduledJobService.cs index 0068600..bf033a3 100644 --- a/Data_Coupler/BackgroundServices/ScheduledJobService.cs +++ b/Data_Coupler/BackgroundServices/ScheduledJobService.cs @@ -286,6 +286,8 @@ public class ScheduledJobService : BackgroundService executionHistory.EndTime = DateTime.Now; executionHistory.Status = "failed"; executionHistory.Message = $"Errore durante l'esecuzione automatica: {ex.Message}"; + // Memorizza il dettaglio completo (stack trace) solo per scopi diagnostici; + // la UI in produzione ne mostrerà una versione sanitizzata senza percorsi di file. executionHistory.ErrorDetails = ex.ToString(); await scheduleService.UpdateExecutionHistoryAsync(executionHistory); } diff --git a/Data_Coupler/Pages/Scheduling.razor.cs b/Data_Coupler/Pages/Scheduling.razor.cs index bef5174..f9d7bcf 100644 --- a/Data_Coupler/Pages/Scheduling.razor.cs +++ b/Data_Coupler/Pages/Scheduling.razor.cs @@ -310,14 +310,21 @@ public partial class Scheduling : ComponentBase : $"Esecuzione fallita: {result.ErrorMessage}"; await ScheduleService.UpdateExecutionStatusAsync(scheduleId, status, message, result.RecordsProcessed); - - if (result.IsSuccess) + + // Notifica l'utente (best-effort: la connessione browser potrebbe essere stata interrotta + // durante un'esecuzione lunga senza che questo invalidi il risultato già salvato). + try { - await ShowSuccessMessage($"Schedulazione eseguita con successo! {result.RecordsProcessed} record elaborati in {result.Duration.TotalSeconds:F2} secondi."); + if (result.IsSuccess) + await ShowSuccessMessage($"Schedulazione eseguita con successo! {result.RecordsProcessed} record elaborati in {result.Duration.TotalSeconds:F2} secondi."); + else + await ShowErrorMessage($"Errore durante l'esecuzione: {result.ErrorMessage}"); } - else + catch (OperationCanceledException) { - await ShowErrorMessage($"Errore durante l'esecuzione: {result.ErrorMessage}"); + // La connessione Blazor è stata interrotta durante l'esecuzione: il risultato è + // già stato salvato correttamente, la notifica non può essere recapitata. + Logger.LogWarning("Notifica UI non inviata per la schedulazione {ScheduleId}: connessione browser interrotta durante l'esecuzione", scheduleId); } await LoadSchedules(); @@ -326,7 +333,7 @@ public partial class Scheduling : ComponentBase { Logger.LogError(ex, "Errore nell'esecuzione manuale schedulazione {ScheduleId}", scheduleId); - // Aggiorna lo storico in caso di eccezione + // Aggiorna lo storico in caso di eccezione durante l'esecuzione effettiva if (executionHistory != null) { executionHistory.EndTime = DateTime.Now; @@ -337,7 +344,15 @@ public partial class Scheduling : ComponentBase } await ScheduleService.UpdateExecutionStatusAsync(scheduleId, "failed", $"Errore: {ex.Message}"); - await ShowErrorMessage("Errore nell'esecuzione: " + ex.Message); + + try + { + await ShowErrorMessage("Errore nell'esecuzione: " + ex.Message); + } + catch (OperationCanceledException) + { + Logger.LogWarning("Notifica UI non inviata per la schedulazione {ScheduleId}: connessione browser non disponibile", scheduleId); + } } finally { diff --git a/Data_Coupler/Pages/SchedulingHistory.razor b/Data_Coupler/Pages/SchedulingHistory.razor index 3892284..eda0144 100644 --- a/Data_Coupler/Pages/SchedulingHistory.razor +++ b/Data_Coupler/Pages/SchedulingHistory.razor @@ -235,7 +235,15 @@ {
@selectedExecution.ErrorDetails+ @if (IsDevelopment) + { +
@selectedExecution.ErrorDetails+ } + else + { +
@GetSanitizedErrorMessage(selectedExecution.ErrorDetails)
+ Per i dettagli tecnici completi consultare i log dell'applicazione. + }