GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Adding per-file exception handling for issues that occur during analyze · HighEncryption/SyncPro@7609e2c

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • SyncPro.Adapters.WindowsFileSystem
    • WindowsFileSystemAdapter.cs
  • SyncPro.Core
    • Adapters
      • SyncEntryChangedFlags.cs
    • Data
      • SyncEntry.cs
    • Runtime
      • AnalyzeJobWorker.cs
      • FlagNameCache.cs
  • SyncPro.UI
    • Navigation/Content
      • AnalyzeJobView.xaml
    • Resources/Graphics
      • warning_16.png
    • SyncPro.UI.csproj
    • ViewModels
      • AnalyzeJobViewModel.cs
      • EntryUpdateInfoViewModel.cs
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎SyncPro.Adapters.WindowsFileSystem/WindowsFileSystemAdapter.cs‎

Copy file name to clipboardExpand all lines: SyncPro.Adapters.WindowsFileSystem/WindowsFileSystemAdapter.cs
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,21 @@ public override void DeleteItem(SyncEntry entry)
217217
entry.EntryLastUpdatedDateTimeUtc = DateTime.UtcNow;
218218
}
219219

220+
/// <summary>
221+
/// Get the <see cref="FileSystemFolder"/> items that are children to the provided
222+
/// <see cref="FileSystemFolder"/>.
223+
/// </summary>
224+
/// <param name="folder">The parent folder</param>
225+
/// <returns>The list of child items under the parent folder.</returns>
226+
/// <remarks>
227+
/// An errors encountered when querying for the list of child should be thrown for the
228+
/// caller to handle. However, any errors related to querying the children themselves
229+
/// should be caught and returned as error information for that child (the original
230+
/// call should not fail in this case).
231+
/// </remarks>
220232
public override IEnumerable<IAdapterItem> GetAdapterItems(IAdapterItem folder)
221233
{
234+
// If folder is null, return the list of top-level folders on the computer (aka drives).
222235
if (folder == null)
223236
{
224237
DriveInfo[] allDrives = DriveInfo.GetDrives();
Collapse file

‎SyncPro.Core/Adapters/SyncEntryChangedFlags.cs‎

Copy file name to clipboardExpand all lines: SyncPro.Core/Adapters/SyncEntryChangedFlags.cs
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ public enum SyncEntryChangedFlags : uint
7373
/// </summary>
7474
Moved = 0x0800,
7575

76+
/// <summary>
77+
/// Indicates that there was an exception while reading this item
78+
/// </summary>
79+
Exception = 0x1000,
80+
7681
/// <summary>
7782
/// Indicates that the change is a new file or directory
7883
/// </summary>
Collapse file

‎SyncPro.Core/Data/SyncEntry.cs‎

Copy file name to clipboardExpand all lines: SyncPro.Core/Data/SyncEntry.cs
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public enum SyncEntryState : short
3333
/// The entry has been deleted from the adapter, but the entry remains in the database
3434
/// </summary>
3535
IsDeleted = 0x02,
36+
37+
/// <summary>
38+
/// Indicates that an error occurred when reading this entry from the source adapter.
39+
/// </summary>
40+
Exception = 0x04,
41+
3642
Undefined = 0xFF
3743
}
3844

Collapse file

‎SyncPro.Core/Runtime/AnalyzeJobWorker.cs‎

Copy file name to clipboardExpand all lines: SyncPro.Core/Runtime/AnalyzeJobWorker.cs
+31-2Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,10 +681,39 @@ private void AnalyzeChangesWithoutChangeTracking(
681681
// TODO: Query the adapter somehow to see if the file should be suppressed (sparse file, for example).
682682
// TODO: Further note - this would be the right place to implement an inclusion/exclusion behavior.
683683

684-
// Check if there was an error reading the item from the adapter. If so, skip the item.
684+
// Check if there was an error reading the item from the adapter. Create a new EntryUpdateInfo object
685+
// for this item so that we know it was found, but don't continue processing the item beyond this.
685686
if (!string.IsNullOrEmpty(sourceAdapterChild.ErrorMessage))
686687
{
687-
Logger.Info("Skipping adapter child '{0}' with error.", sourceAdapterChild.FullName);
688+
// Check if there is an entry in the database that matches the unique ID of the item
689+
SyncEntry sourceLogicalChildEx = logicalChildren?.FirstOrDefault(c => c.HasUniqueId(sourceAdapterChild.UniqueId));
690+
691+
// There isn't a database entry for this item, so we will need to create one. It won't be added
692+
// to the database, but we will need it since other code expects it to be there.
693+
if (sourceLogicalChildEx == null)
694+
{
695+
sourceLogicalChildEx = new SyncEntry
696+
{
697+
Name = sourceAdapterChild.Name,
698+
AdapterEntries = new List<SyncEntryAdapterData>(),
699+
ParentEntry = logicalParent
700+
};
701+
}
702+
703+
sourceLogicalChildEx.State = SyncEntryState.NotSynchronized;
704+
705+
// Create the update info for the new entry. The only flag we want to set if Exception so that
706+
// it isn't processed in a sync job.
707+
sourceLogicalChildEx.UpdateInfo = new EntryUpdateInfo(
708+
sourceLogicalChildEx,
709+
sourceAdapter,
710+
SyncEntryChangedFlags.Exception,
711+
Path.Combine(relativePath, sourceLogicalChildEx.Name));
712+
713+
this.RaiseChangeDetected(sourceAdapter.Configuration.Id, sourceLogicalChildEx.UpdateInfo);
714+
715+
this.LogSyncAnalyzerChangeFound(sourceLogicalChildEx);
716+
688717
continue;
689718
}
690719

Collapse file

‎SyncPro.Core/Runtime/FlagNameCache.cs‎

Copy file name to clipboardExpand all lines: SyncPro.Core/Runtime/FlagNameCache.cs
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ private static string BuildFlagString(SyncEntryChangedFlags flags)
9898
sb.Append("Moved,");
9999
}
100100

101+
if ((flags & SyncEntryChangedFlags.Exception) != 0)
102+
{
103+
sb.Append("Exception,");
104+
}
105+
101106
return sb.ToString(0, sb.Length - 1);
102107
}
103108
}
Collapse file

‎SyncPro.UI/Navigation/Content/AnalyzeJobView.xaml‎

Copy file name to clipboardExpand all lines: SyncPro.UI/Navigation/Content/AnalyzeJobView.xaml
+31-3Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@
3333
</Style>
3434

3535
<DataTemplate x:Key="RelativePathCellTemplate" DataType="{x:Type viewModels:EntryUpdateInfoViewModel}">
36-
<TextBlock x:Name="TextBox" Text="{Binding Path=RelativePath}" Style="{StaticResource TreeListItemStyle}" />
36+
<StackPanel Orientation="Horizontal">
37+
<TextBlock x:Name="TextBox" Text="{Binding Path=RelativePath}" Style="{StaticResource TreeListItemStyle}" />
38+
<Image Source="/Resources/Graphics/icon_exclaim.png" Height="16" Margin="4,0,0,0"
39+
Visibility="{Binding Path=Flags, Converter={StaticResource EnumToVisibility}, ConverterParameter=Exception}"/>
40+
</StackPanel>
3741
</DataTemplate>
3842

3943
<DataTemplate x:Key="ChangeTypeCellTemplate" DataType="{x:Type viewModels:EntryUpdateInfoViewModel}">
@@ -62,6 +66,9 @@
6266
<DataTrigger Binding="{Binding Path=IsDirectory}" Value="True">
6367
<Setter Property="Visibility" Value="Collapsed" />
6468
</DataTrigger>
69+
<DataTrigger Binding="{Binding Path=Flags, Converter={StaticResource EnumToBoolean}, ConverterParameter=Exception}" Value="True">
70+
<Setter Property="Visibility" Value="Collapsed" />
71+
</DataTrigger>
6572
</Style.Triggers>
6673
</Style>
6774
</TextBlock.Style>
@@ -216,8 +223,29 @@
216223
<ItemsControl ItemsSource="{Binding Path=AnalyzeJobViewModel.ErrorMessages}">
217224
<ItemsControl.ItemTemplate>
218225
<DataTemplate DataType="viewModels:ErrorViewModel">
219-
<TextBlock Text="{Binding Path=Header}"
220-
ToolTip="{Binding Path=Message}" />
226+
<Grid>
227+
<Grid.ColumnDefinitions>
228+
<ColumnDefinition Width="Auto" />
229+
<ColumnDefinition />
230+
</Grid.ColumnDefinitions>
231+
232+
<Image Width="16">
233+
<Image.Style>
234+
<Style TargetType="Image">
235+
<Style.Setters>
236+
<Setter Property="Source" Value="/Resources/Graphics/icon_exclaim.png" />
237+
</Style.Setters>
238+
<Style.Triggers>
239+
<DataTrigger Binding="{Binding Path=IsWarning}" Value="True">
240+
<Setter Property="Source" Value="/Resources/Graphics/warning_16.png" />
241+
</DataTrigger>
242+
</Style.Triggers>
243+
</Style>
244+
</Image.Style>
245+
</Image>
246+
<TextBlock Grid.Column="1" Text="{Binding Path=Header}"
247+
ToolTip="{Binding Path=Message}" />
248+
</Grid>
221249
</DataTemplate>
222250
</ItemsControl.ItemTemplate>
223251
</ItemsControl>
Collapse file

‎SyncPro.UI/Resources/Graphics/warning_16.png‎

Copy file name to clipboard
478 Bytes
  • Display the source diff
  • Display the rich diff
Loading
Collapse file

‎SyncPro.UI/SyncPro.UI.csproj‎

Copy file name to clipboardExpand all lines: SyncPro.UI/SyncPro.UI.csproj
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,9 @@
657657
<ItemGroup>
658658
<Resource Include="Resources\Graphics\help_20.png" />
659659
</ItemGroup>
660+
<ItemGroup>
661+
<Resource Include="Resources\Graphics\warning_16.png" />
662+
</ItemGroup>
660663
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
661664
<PropertyGroup>
662665
<PreBuildEvent>git describe --always --dirty &gt; $(ProjectDir)\version.txt</PreBuildEvent>
Collapse file

‎SyncPro.UI/ViewModels/AnalyzeJobViewModel.cs‎

Copy file name to clipboardExpand all lines: SyncPro.UI/ViewModels/AnalyzeJobViewModel.cs
+43-10Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,25 +118,58 @@ private void OnJobFinished(object sender, EventArgs eventArgs)
118118
this.ChangeMetricsList[1].Unchanged = this.AnalyzeJob.AnalyzeResult.UnchangedFolderCount;
119119
this.ChangeMetricsList[2].Unchanged = this.AnalyzeJob.AnalyzeResult.UnchangedFileBytes;
120120

121-
List<Exception> exceptions =
122-
this.AnalyzeJob.AnalyzeResult.AdapterResults
123-
.Select(r => r.Value.Exception)
124-
.ToList();
125-
126-
if (exceptions.Any())
121+
int entryErrorCount = 0;
122+
foreach (KeyValuePair<int, AnalyzeAdapterResult> adapterResult in this.AnalyzeJob.AnalyzeResult.AdapterResults)
127123
{
128-
foreach (Exception exception in exceptions)
124+
if (adapterResult.Value.Exception != null)
129125
{
130126
this.ErrorMessages.Add(
131127
new ErrorViewModel(
132128
false,
133-
exception.Message,
134-
exception.ToString()));
129+
adapterResult.Value.Exception.Message,
130+
adapterResult.Value.Exception.ToString()));
131+
132+
this.ProgressState = ProgressState.Error;
135133
}
136134

137-
this.ProgressState = ProgressState.Error;
135+
entryErrorCount +=
136+
adapterResult.Value.EntryResults.Count(e => e.HasSyncEntryFlag(SyncEntryChangedFlags.Exception));
137+
}
138+
139+
if (entryErrorCount > 0)
140+
{
141+
var errorViewModel = new ErrorViewModel(
142+
false,
143+
string.Format(
144+
"Error were encountered while analyzing {0} items. These items will not be synchronized.",
145+
entryErrorCount),
146+
null);
147+
148+
App.DispatcherInvoke(() => this.ErrorMessages.Add(errorViewModel));
138149
}
139150

151+
//// Performance of this call isn't great, but there shouldn't be a large number of exceptions
152+
//// to process in this way.
153+
//List<Exception> exceptions =
154+
// this.AnalyzeJob.AnalyzeResult.AdapterResults
155+
// .Where(r => r.Value.Exception != null)
156+
// .Select(r => r.Value.Exception)
157+
// .ToList();
158+
159+
//if (exceptions.Any())
160+
//{
161+
// foreach (Exception exception in exceptions)
162+
// {
163+
// this.ErrorMessages.Add(
164+
// new ErrorViewModel(
165+
// false,
166+
// exception.Message,
167+
// exception.ToString()));
168+
// }
169+
170+
// this.ProgressState = ProgressState.Error;
171+
//}
172+
140173
this.metadataUpdateCancellationToken.Cancel();
141174

142175
App.DispatcherInvoke(CommandManager.InvalidateRequerySuggested);
Collapse file

‎SyncPro.UI/ViewModels/EntryUpdateInfoViewModel.cs‎

Copy file name to clipboardExpand all lines: SyncPro.UI/ViewModels/EntryUpdateInfoViewModel.cs
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ private static IList<string> GetChangeNamesFromFlags(SyncEntryChangedFlags flags
391391
changes.Add("Destination Exists");
392392
}
393393

394+
if ((flags & SyncEntryChangedFlags.Exception) == SyncEntryChangedFlags.Exception)
395+
{
396+
changes.Add("[Exception]");
397+
}
398+
394399
return changes;
395400
}
396401

0 commit comments

Comments
0 (0)
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.