Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SP-2273: Added error-checking code to try to recover from errors… #157

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SayMore.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=curr/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dropbox/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=fsutil/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jira/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Insite/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mets/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NTSC/@EntryIndexedValue">True</s:Boolean>
Expand Down
85 changes: 67 additions & 18 deletions src/SayMore/Model/ElementRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@
using System.Xml;
using SIL.Code;
using SIL.Windows.Forms.FileSystem;
using SayMore.Model.Files;
using SayMore.UI.ProjectWindow;
using SIL.Reporting;
using L10NSharp;
using FileType = SayMore.Model.Files.FileType;
using System.Threading;

namespace SayMore.Model
{
/// ----------------------------------------------------------------------------------------
public class ElementIdChangedArgs : EventArgs
{
public ProjectElement Element { get; private set; }
public string OldId { get; private set; }
public string NewId { get; private set; }
public ProjectElement Element { get; }
public string OldId { get; }
public string NewId { get; }

/// ------------------------------------------------------------------------------------
public ElementIdChangedArgs(ProjectElement element, string oldId, string newId)
Expand Down Expand Up @@ -67,26 +69,79 @@ public ElementRepository(string projectDirectory, string elementGroupName,
[Obsolete("For Mocking Only")]
public ElementRepository(){}

public List<XmlException> FileLoadErrors { get; private set; }
public List<XmlException> FileLoadErrors { get; }

/// ------------------------------------------------------------------------------------
/// <summary>
/// Updates the list of items by looking in the file system for all the subfolders
/// in the project's folder corresponding to this repository.
/// </summary>
/// <remarks>Any file load errors ocurring during this call will be noted in
/// <remarks>Any file load errors occurring during this call will be noted in
/// FileLoadErrors. Caller is responsible for checking this and handling them as
/// appropriate.</remarks>
/// ------------------------------------------------------------------------------------
public void RefreshItemList()
{
FileLoadErrors.Clear();

var folders = new HashSet<string>(Directory.GetDirectories(_rootFolder));
// SP-2273...
// I have not found a way to re-create this bug, and indeed it appears to be
// quasi-impossible. User says the folder does exist. I've tried deleting or renaming
// the folder while SayMore is running, but the OS won't let me. I think the crux of
// the issue must be hidden in the user's statement "I was backing up my files to
// OneDrive and sharing a SayMore project file while on a zoom meeting." Not quite
// sure what that even means, but maybe OneDrive or the "sharing" somehow made it
// possible for the folder to be temporarily renamed or otherwise put into a state
// where it appeared not to exist.
string[] sessionDirectories = null;
var retry = false;
do
{
try
{
sessionDirectories = Directory.GetDirectories(_rootFolder);
}
catch (Exception e)
{
if (retry)
throw;

if (e is DirectoryNotFoundException)
{
Thread.Sleep(200); // Give it a fighting chance in case it was something transient.
if (Directory.Exists(_rootFolder))
{
retry = true;
continue;
}
}
if (e is IOException || e is UnauthorizedAccessException)
{
ErrorReport.ReportNonFatalExceptionWithMessage(e,
string.Format(LocalizationManager.GetString(
"MainWindow.ElementFolderMissingOrUnavailable",
"It looks like the {0} folder is no longer accessible. If you " +
"are able to fix this, {1} will retry. Otherwise, please report " +
"this ({2}).",
"Param 0: element type (\"Session\" or \"Person\"); "+
"Param 1: \"SayMore\" (program name); "+
"Param 2: Jira issue number (for developers)"),
ElementFileType.Name, Program.ProductName, "SP-2273"));
if (!Directory.Exists(_rootFolder))
throw;
retry = true;
}
else
throw;
}
} while (retry);
// ...SP-2273

var folders = new HashSet<string>(sessionDirectories);

// Go through the existing sessions we have and remove
// any that no longer have a sessions folder.
for (int i = _items.Count() - 1; i >= 0; i--)
for (int i = _items.Count - 1; i >= 0; i--)
{
if (!folders.Contains(_items[i].FolderPath))
_items.RemoveAt(i);
Expand Down Expand Up @@ -116,19 +171,13 @@ public void RefreshItemList()
}

/// ------------------------------------------------------------------------------------
public virtual IEnumerable<T> AllItems
{
get { return _items; }
}
public virtual IEnumerable<T> AllItems => _items;

/// ------------------------------------------------------------------------------------
public virtual string PathToFolder
{
get { return _rootFolder; }
}
public virtual string PathToFolder => _rootFolder;

/// ------------------------------------------------------------------------------------
public FileType ElementFileType { get; private set; }
public FileType ElementFileType { get; }

/// ------------------------------------------------------------------------------------
public T CreateNew(string id)
Expand Down