Skip to content

Commit 0faae3f

Browse files
committed
Introduced catch, log and swallow approach for all exceptions in delegates dispatched to the UI thread.
1 parent 096c085 commit 0faae3f

File tree

8 files changed

+168
-91
lines changed

8 files changed

+168
-91
lines changed

RetailCoder.VBE/Navigation/CodeExplorer/CodeExplorerViewModel.cs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public sealed class CodeExplorerViewModel : ViewModelBase, IDisposable
3535
private GeneralSettings _generalSettings;
3636
private WindowSettings _windowSettings;
3737

38+
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
39+
3840
public CodeExplorerViewModel(FolderHelper folderHelper, RubberduckParserState state, List<CommandBase> commands,
3941
IConfigProvider<GeneralSettings> generalSettingsProvider, IConfigProvider<WindowSettings> windowSettingsProvider)
4042
{
@@ -395,22 +397,30 @@ private void ParserState_ModuleStateChanged(object sender, Parsing.ParseProgress
395397

396398
UiDispatcher.Invoke(() =>
397399
{
398-
if (folderNode == null)
400+
try
399401
{
400-
folderNode = new CodeExplorerCustomFolderViewModel(projectNode, projectName, projectName);
401-
projectNode.AddChild(folderNode);
402+
if (folderNode == null)
403+
{
404+
folderNode = new CodeExplorerCustomFolderViewModel(projectNode, projectName, projectName);
405+
projectNode.AddChild(folderNode);
406+
}
407+
408+
var declaration = CreateDeclaration(e.Module);
409+
var newNode =
410+
new CodeExplorerComponentViewModel(folderNode, declaration, new List<Declaration>())
411+
{
412+
IsErrorState = true
413+
};
414+
415+
folderNode.AddChild(newNode);
416+
417+
// Force a refresh. OnPropertyChanged("Projects") didn't work.
418+
Projects = Projects;
402419
}
403-
404-
var declaration = CreateDeclaration(e.Module);
405-
var newNode = new CodeExplorerComponentViewModel(folderNode, declaration, new List<Declaration>())
420+
catch (Exception exception)
406421
{
407-
IsErrorState = true
408-
};
409-
410-
folderNode.AddChild(newNode);
411-
412-
// Force a refresh. OnPropertyChanged("Projects") didn't work.
413-
Projects = Projects;
422+
Logger.Error(exception, "Exception thrown trying to refresh the code explorer view on the UI thread.");
423+
}
414424
});
415425
}
416426
}

RetailCoder.VBE/UI/Command/FindAllImplementationsCommand.cs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class FindAllImplementationsCommand : CommandBase, IDisposable
2727
private readonly SearchResultPresenterInstanceManager _presenterService;
2828
private readonly IVBE _vbe;
2929

30+
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
31+
3032
public FindAllImplementationsCommand(INavigateCommand navigateCommand, IMessageBox messageBox,
3133
RubberduckParserState state, IVBE vbe, ISearchResultsWindowViewModel viewModel,
3234
SearchResultPresenterInstanceManager presenterService)
@@ -63,29 +65,36 @@ private void _state_StateChanged(object sender, ParserStateEventArgs e)
6365

6466
private void UpdateTab()
6567
{
66-
var findImplementationsTabs = _viewModel.Tabs.Where(
67-
t => t.Header.StartsWith(RubberduckUI.AllImplementations_Caption.Replace("'{0}'", ""))).ToList();
68-
69-
foreach (var tab in findImplementationsTabs)
68+
try
7069
{
71-
var newTarget = FindNewDeclaration(tab.Target);
72-
if (newTarget == null)
73-
{
74-
tab.CloseCommand.Execute(null);
75-
return;
76-
}
70+
var findImplementationsTabs = _viewModel.Tabs.Where(
71+
t => t.Header.StartsWith(RubberduckUI.AllImplementations_Caption.Replace("'{0}'", ""))).ToList();
7772

78-
var vm = CreateViewModel(newTarget);
79-
if (vm.SearchResults.Any())
73+
foreach (var tab in findImplementationsTabs)
8074
{
81-
tab.SearchResults = vm.SearchResults;
82-
tab.Target = vm.Target;
83-
}
84-
else
85-
{
86-
tab.CloseCommand.Execute(null);
75+
var newTarget = FindNewDeclaration(tab.Target);
76+
if (newTarget == null)
77+
{
78+
tab.CloseCommand.Execute(null);
79+
return;
80+
}
81+
82+
var vm = CreateViewModel(newTarget);
83+
if (vm.SearchResults.Any())
84+
{
85+
tab.SearchResults = vm.SearchResults;
86+
tab.Target = vm.Target;
87+
}
88+
else
89+
{
90+
tab.CloseCommand.Execute(null);
91+
}
8792
}
8893
}
94+
catch (Exception exception)
95+
{
96+
Logger.Error(exception, "Exception thrown while trying to update the find implementations tab.");
97+
}
8998
}
9099

91100
protected override bool EvaluateCanExecute(object parameter)

RetailCoder.VBE/UI/Command/FindAllReferencesCommand.cs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,36 @@ private void _state_StateChanged(object sender, ParserStateEventArgs e)
6161

6262
private void UpdateTab()
6363
{
64-
var findReferenceTabs = _viewModel.Tabs.Where(
65-
t => t.Header.StartsWith(RubberduckUI.AllReferences_Caption.Replace("'{0}'", ""))).ToList();
66-
67-
foreach (var tab in findReferenceTabs)
64+
try
6865
{
69-
var newTarget = FindNewDeclaration(tab.Target);
70-
if (newTarget == null)
71-
{
72-
tab.CloseCommand.Execute(null);
73-
return;
74-
}
66+
var findReferenceTabs = _viewModel.Tabs.Where(
67+
t => t.Header.StartsWith(RubberduckUI.AllReferences_Caption.Replace("'{0}'", ""))).ToList();
7568

76-
var vm = CreateViewModel(newTarget);
77-
if (vm.SearchResults.Any())
69+
foreach (var tab in findReferenceTabs)
7870
{
79-
tab.SearchResults = vm.SearchResults;
80-
tab.Target = vm.Target;
81-
}
82-
else
83-
{
84-
tab.CloseCommand.Execute(null);
71+
var newTarget = FindNewDeclaration(tab.Target);
72+
if (newTarget == null)
73+
{
74+
tab.CloseCommand.Execute(null);
75+
return;
76+
}
77+
78+
var vm = CreateViewModel(newTarget);
79+
if (vm.SearchResults.Any())
80+
{
81+
tab.SearchResults = vm.SearchResults;
82+
tab.Target = vm.Target;
83+
}
84+
else
85+
{
86+
tab.CloseCommand.Execute(null);
87+
}
8588
}
8689
}
90+
catch (Exception exception)
91+
{
92+
Logger.Error(exception, "Exception thrown while trying to update the find all references tab.");
93+
}
8794
}
8895

8996
protected override bool EvaluateCanExecute(object parameter)

RetailCoder.VBE/UI/Command/MenuItems/CommandBars/RubberduckCommandBar.cs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,19 @@ private void SetStatusLabelCaption(string caption, int? errorCount = null)
107107

108108
UiDispatcher.Invoke(() =>
109109
{
110-
reparseCommandButton.SetCaption(caption);
111-
reparseCommandButton.SetToolTip(string.Format(RubberduckUI.ReparseToolTipText, caption));
112-
if (errorCount.HasValue && errorCount.Value > 0)
110+
try
113111
{
114-
showErrorsCommandButton.SetToolTip(string.Format(RubberduckUI.ParserErrorToolTipText, errorCount.Value));
112+
reparseCommandButton.SetCaption(caption);
113+
reparseCommandButton.SetToolTip(string.Format(RubberduckUI.ReparseToolTipText, caption));
114+
if (errorCount.HasValue && errorCount.Value > 0)
115+
{
116+
showErrorsCommandButton.SetToolTip(
117+
string.Format(RubberduckUI.ParserErrorToolTipText, errorCount.Value));
118+
}
119+
}
120+
catch (Exception exception)
121+
{
122+
Logger.Error(exception, "Exception thrown trying to set the status label caption on the UI thread.");
115123
}
116124
});
117125
Localize();
@@ -125,9 +133,16 @@ private void SetContextSelectionCaption(string caption, int contextReferenceCoun
125133

126134
UiDispatcher.Invoke(() =>
127135
{
128-
contextLabel?.SetCaption(caption);
129-
contextReferences?.SetCaption(contextReferenceCount);
130-
contextDescription?.SetCaption(description);
136+
try
137+
{
138+
contextLabel?.SetCaption(caption);
139+
contextReferences?.SetCaption(contextReferenceCount);
140+
contextDescription?.SetCaption(description);
141+
}
142+
catch (Exception exception)
143+
{
144+
Logger.Error(exception, "Exception thrown trying to set the context selection caption on the UI thread.");
145+
}
131146
});
132147
Localize();
133148
}

RetailCoder.VBE/UI/Command/MenuItems/UiDispatcher.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Threading;
33
using System.Windows.Threading;
4+
using NLog;
45

56
namespace Rubberduck.UI.Command.MenuItems
67
{
@@ -61,7 +62,11 @@ private static void CheckInitialization()
6162

6263
public static void Shutdown()
6364
{
64-
Invoke(() => Dispatcher.CurrentDispatcher.InvokeShutdown());
65+
Invoke(() =>
66+
{
67+
LogManager.GetCurrentClassLogger().Debug("Invoking shutdown on UI thread dispatcher.");
68+
Dispatcher.CurrentDispatcher.InvokeShutdown();
69+
});
6570
}
6671
}
6772
}

RetailCoder.VBE/UI/Command/ShowParserErrorsCommand.cs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,36 @@ private void _state_StateChanged(object sender, ParserStateEventArgs e)
4747

4848
private void UpdateTab()
4949
{
50-
if (_viewModel == null)
50+
try
5151
{
52-
return;
53-
}
52+
if (_viewModel == null)
53+
{
54+
return;
55+
}
5456

55-
var vm = CreateViewModel();
57+
var vm = CreateViewModel();
5658

57-
var tab = _viewModel.Tabs.FirstOrDefault(t => t.Header == RubberduckUI.Parser_ParserError);
58-
if (tab != null)
59-
{
60-
if (_state.Status != ParserState.Error)
59+
var tab = _viewModel.Tabs.FirstOrDefault(t => t.Header == RubberduckUI.Parser_ParserError);
60+
if (tab != null)
6161
{
62-
tab.CloseCommand.Execute(null);
62+
if (_state.Status != ParserState.Error)
63+
{
64+
tab.CloseCommand.Execute(null);
65+
}
66+
else
67+
{
68+
tab.SearchResults = vm.SearchResults;
69+
}
6370
}
64-
else
71+
else if (_state.Status == ParserState.Error)
6572
{
66-
tab.SearchResults = vm.SearchResults;
73+
_viewModel.AddTab(vm);
74+
_viewModel.SelectedTab = vm;
6775
}
6876
}
69-
else if (_state.Status == ParserState.Error)
77+
catch (Exception exception)
7078
{
71-
_viewModel.AddTab(vm);
72-
_viewModel.SelectedTab = vm;
79+
Logger.Error(exception, "Exception thrown while trying to update the parser errors tab.");
7380
}
7481
}
7582

RetailCoder.VBE/UI/Inspections/InspectionResultsViewModel.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public sealed class InspectionResultsViewModel : ViewModelBase, INavigateSelecti
4141
private readonly IGeneralConfigService _configService;
4242
private readonly IOperatingSystem _operatingSystem;
4343

44+
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
45+
4446
public InspectionResultsViewModel(RubberduckParserState state, IInspector inspector, IQuickFixProvider quickFixProvider,
4547
INavigateCommand navigateCommand, ReparseCommand reparseCommand,
4648
IClipboardWriter clipboard, IGeneralConfigService configService, IOperatingSystem operatingSystem)
@@ -305,10 +307,17 @@ private async void RefreshInspections()
305307

306308
UiDispatcher.Invoke(() =>
307309
{
308-
IsBusy = false;
309-
OnPropertyChanged("EmptyUIRefreshVisibility");
310-
IsRefreshing = false;
311-
SelectedItem = null;
310+
try
311+
{
312+
IsBusy = false;
313+
OnPropertyChanged("EmptyUIRefreshVisibility");
314+
IsRefreshing = false;
315+
SelectedItem = null;
316+
}
317+
catch (Exception exception)
318+
{
319+
Logger.Error(exception, "Exception thrown trying to refresh the inspection results view on th UI thread.");
320+
}
312321
});
313322

314323
stopwatch.Stop();

RetailCoder.VBE/UI/SourceControl/SourceControlViewViewModel.cs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,16 @@ private void ResetView()
209209

210210
UiDispatcher.InvokeAsync(() =>
211211
{
212-
foreach (var tab in _tabItems)
212+
try
213+
{
214+
foreach (var tab in _tabItems)
215+
{
216+
tab.ViewModel.ResetView();
217+
}
218+
}
219+
catch (Exception exception)
213220
{
214-
tab.ViewModel.ResetView();
221+
Logger.Error(exception, "Exception thrown while trying to reset the source control view on the UI thread.");
215222
}
216223
});
217224
}
@@ -901,26 +908,34 @@ private void OpenRepoAssignedToProject()
901908

902909
private void Refresh()
903910
{
904-
_fileSystemWatcher.EnableRaisingEvents = false;
905-
Logger.Trace("FileSystemWatcher.EnableRaisingEvents is disabled.");
906-
907-
if(Provider == null)
908-
{
909-
OpenRepoAssignedToProject();
910-
}
911-
else
911+
try
912912
{
913-
foreach (var tab in TabItems)
913+
_fileSystemWatcher.EnableRaisingEvents = false;
914+
Logger.Trace("FileSystemWatcher.EnableRaisingEvents is disabled.");
915+
916+
if (Provider == null)
914917
{
915-
tab.ViewModel.RefreshView();
918+
OpenRepoAssignedToProject();
916919
}
917-
918-
if(Directory.Exists(Provider.CurrentRepository.LocalLocation))
920+
else
919921
{
920-
_fileSystemWatcher.EnableRaisingEvents = true;
921-
Logger.Trace("FileSystemWatcher.EnableRaisingEvents is enabled.");
922+
foreach (var tab in TabItems)
923+
{
924+
tab.ViewModel.RefreshView();
925+
}
926+
927+
if (Directory.Exists(Provider.CurrentRepository.LocalLocation))
928+
{
929+
_fileSystemWatcher.EnableRaisingEvents = true;
930+
Logger.Trace("FileSystemWatcher.EnableRaisingEvents is enabled.");
931+
}
922932
}
923933
}
934+
catch (Exception exception)
935+
{
936+
//We catch and log everything since this generally gets dispatched to the UI thread.
937+
Logger.Error(exception, "Exception while trying to refresh th source control view.");
938+
}
924939
}
925940

926941
private bool ValidRepoExists()

0 commit comments

Comments
 (0)