From b40668469e6108ed85e46bb345cfb53ca6feb612 Mon Sep 17 00:00:00 2001 From: Julien W <50249422+julien-wff@users.noreply.github.com> Date: Fri, 15 Dec 2023 16:09:02 +0100 Subject: [PATCH] feat: job error handling --- EasyGUI/Controls/JobDisplay.xaml | 4 +++ EasyGUI/Controls/JobDisplay.xaml.cs | 38 +++++++++++++++++++++++- EasyGUI/Resources/Strings.Designer.cs | 27 +++++++++++++++++ EasyGUI/Resources/Strings.fr.Designer.cs | 27 +++++++++++++++++ EasyGUI/Resources/Strings.fr.resx | 9 ++++++ EasyGUI/Resources/Strings.resx | 9 ++++++ EasyLib/Events/IJobStatusSubscriber.cs | 2 +- EasyLib/Job/Job.cs | 22 +++++++++++++- EasyLib/JobManager.cs | 2 +- 9 files changed, 136 insertions(+), 4 deletions(-) diff --git a/EasyGUI/Controls/JobDisplay.xaml b/EasyGUI/Controls/JobDisplay.xaml index 329b366..b3d9335 100644 --- a/EasyGUI/Controls/JobDisplay.xaml +++ b/EasyGUI/Controls/JobDisplay.xaml @@ -84,6 +84,10 @@ x:Name="PausedBreadCrumb" BreadCrumbText="{x:Static resx:Strings.JobState_Paused}" BreadCrumbColor="{StaticResource OrangeBrush}" Margin="0,0,8,0" /> + diff --git a/EasyGUI/Controls/JobDisplay.xaml.cs b/EasyGUI/Controls/JobDisplay.xaml.cs index bfac388..31650cf 100644 --- a/EasyGUI/Controls/JobDisplay.xaml.cs +++ b/EasyGUI/Controls/JobDisplay.xaml.cs @@ -6,10 +6,12 @@ using System.Windows; using System.Windows.Input; using EasyGUI.Events; +using EasyGUI.Resources; using EasyLib.Enums; using EasyLib.Events; using EasyLib.Job; using Application = System.Windows.Application; +using MessageBox = System.Windows.MessageBox; namespace EasyGUI.Controls; @@ -36,6 +38,10 @@ public partial class JobDisplay : INotifyPropertyChanged, IJobStatusSubscriber new PropertyMetadata(default(ObservableCollection)) ); + private readonly object _errorMessageLock = new(); + + private string? _errorMessage; + private bool _isJobSelectedLocked; private bool _selectedJobsLocked; @@ -80,7 +86,11 @@ public string JobProgressText public void OnJobStateChange(JobState state, Job job) { - Application.Current.Dispatcher.Invoke(() => OnPropertyChanged(nameof(Job))); + Application.Current.Dispatcher.Invoke(() => + { + _errorMessage = null; + OnPropertyChanged(nameof(Job)); + }); } public void OnJobProgress(Job job) @@ -88,6 +98,31 @@ public void OnJobProgress(Job job) Application.Current.Dispatcher.Invoke(() => OnPropertyChanged(nameof(Job))); } + public void OnJobError(Exception error) + { + lock (_errorMessageLock) + { + if (_errorMessage != null) + return; + + _errorMessage = error.Message; + } + + Application.Current.Dispatcher.Invoke(() => + { + var jobName = Job.Name; + + Task.Run(() => MessageBox.Show( + string.Format(Strings.JobDisplay_ErrorPopup_Message, jobName, error.Message), + Strings.JobDisplay_ErrorPopup_Title, + MessageBoxButton.OK, + MessageBoxImage.Error + )); + + OnPropertyChanged(nameof(Job)); + }); + } + public event PropertyChangedEventHandler? PropertyChanged; public event EventHandler? JobStarted; public event EventHandler? JobEdited; @@ -127,6 +162,7 @@ private void UpdateBreadcrumbs() SetElementVisibility(StructureBreadCrumb, Job.State == JobState.DestinationStructureCreation); SetElementVisibility(CopyBreadCrumb, Job.State == JobState.Copy); SetElementVisibility(PausedBreadCrumb, Job.State != JobState.End && !Job.CurrentlyRunning); + SetElementVisibility(ErrorBreadCrumb, !string.IsNullOrEmpty(_errorMessage)); } private void UpdateButtons() diff --git a/EasyGUI/Resources/Strings.Designer.cs b/EasyGUI/Resources/Strings.Designer.cs index 71b6a7f..bf93f5c 100644 --- a/EasyGUI/Resources/Strings.Designer.cs +++ b/EasyGUI/Resources/Strings.Designer.cs @@ -187,6 +187,24 @@ public static string JobCreatePopup_JobType { } } + /// + /// Looks up a localized string similar to An error occured during the execution of {0}: {1}. + /// + public static string JobDisplay_ErrorPopup_Message { + get { + return ResourceManager.GetString("JobDisplay_ErrorPopup_Message", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Job error. + /// + public static string JobDisplay_ErrorPopup_Title { + get { + return ResourceManager.GetString("JobDisplay_ErrorPopup_Title", resourceCulture); + } + } + /// /// Looks up a localized string similar to Copy. /// @@ -223,6 +241,15 @@ public static string JobState_End { } } + /// + /// Looks up a localized string similar to Error. + /// + public static string JobState_Error { + get { + return ResourceManager.GetString("JobState_Error", resourceCulture); + } + } + /// /// Looks up a localized string similar to Paused. /// diff --git a/EasyGUI/Resources/Strings.fr.Designer.cs b/EasyGUI/Resources/Strings.fr.Designer.cs index e704572..2b56922 100644 --- a/EasyGUI/Resources/Strings.fr.Designer.cs +++ b/EasyGUI/Resources/Strings.fr.Designer.cs @@ -187,6 +187,24 @@ public static string JobCreatePopup_JobType { } } + /// + /// Looks up a localized string similar to Une erreur est survenue pendant l'exécution de la tâche {0} : {1}. + /// + public static string JobDisplay_ErrorPopup_Message { + get { + return ResourceManager.GetString("JobDisplay_ErrorPopup_Message", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Erreur de tâche. + /// + public static string JobDisplay_ErrorPopup_Title { + get { + return ResourceManager.GetString("JobDisplay_ErrorPopup_Title", resourceCulture); + } + } + /// /// Looks up a localized string similar to Copie. /// @@ -223,6 +241,15 @@ public static string JobState_End { } } + /// + /// Looks up a localized string similar to Erreur. + /// + public static string JobState_Error { + get { + return ResourceManager.GetString("JobState_Error", resourceCulture); + } + } + /// /// Looks up a localized string similar to En pause. /// diff --git a/EasyGUI/Resources/Strings.fr.resx b/EasyGUI/Resources/Strings.fr.resx index affdd7a..cbfc1a4 100644 --- a/EasyGUI/Resources/Strings.fr.resx +++ b/EasyGUI/Resources/Strings.fr.resx @@ -148,4 +148,13 @@ Nous nous excusons pour la gêne occasionnée. + + Erreur + + + Erreur de tâche + + + Une erreur est survenue pendant l'exécution de la tâche {0} : {1} + \ No newline at end of file diff --git a/EasyGUI/Resources/Strings.resx b/EasyGUI/Resources/Strings.resx index d0f9d20..ec6ce9f 100644 --- a/EasyGUI/Resources/Strings.resx +++ b/EasyGUI/Resources/Strings.resx @@ -148,4 +148,13 @@ We are sorry for this inconvenience. + + Error + + + Job error + + + An error occured during the execution of {0}: {1} + \ No newline at end of file diff --git a/EasyLib/Events/IJobStatusSubscriber.cs b/EasyLib/Events/IJobStatusSubscriber.cs index 8caffee..2b1438c 100644 --- a/EasyLib/Events/IJobStatusSubscriber.cs +++ b/EasyLib/Events/IJobStatusSubscriber.cs @@ -18,7 +18,7 @@ public void OnJobStateChange(JobState state, Job.Job job) /// Event triggered when an error occurs during the job /// /// - public void OnJobError(string error) + public void OnJobError(Exception error) { // Implementation optional } diff --git a/EasyLib/Job/Job.cs b/EasyLib/Job/Job.cs index e0f2566..0a3115a 100644 --- a/EasyLib/Job/Job.cs +++ b/EasyLib/Job/Job.cs @@ -159,7 +159,19 @@ private bool Start(bool resume) var folders = selector.SelectFolders(directories, lastFolder, Type, DestinationFolder); // Run the job in a new thread - var thread = new Thread(() => JobSteps(transferManager, folders)); + var thread = new Thread(() => + { + try + { + JobSteps(transferManager, folders); + } + catch (Exception e) + { + CurrentlyRunning = false; + Pause(); + _notifySubscribersForError(e); + } + }); thread.Start(); return true; } @@ -249,6 +261,14 @@ private void _notifySubscribersForChangeState(JobState subState) } } + private void _notifySubscribersForError(Exception error) + { + foreach (var subscriber in Subscribers) + { + subscriber.OnJobError(error); + } + } + private void _setJobState(JobState pubState) { State = pubState; diff --git a/EasyLib/JobManager.cs b/EasyLib/JobManager.cs index a057265..da1dbc3 100644 --- a/EasyLib/JobManager.cs +++ b/EasyLib/JobManager.cs @@ -50,7 +50,7 @@ public void Unsubscribe(IJobStatusSubscriber subscriber) _subscribers.Remove(subscriber); } - public void OnJobError(string error) + public void OnJobError(Exception error) { foreach (var subscriber in _subscribers) {