Skip to content

Commit 562e839

Browse files
authored
Reworked filesystem exception handling (#2269)
2 parents 26ee9b8 + 83ed139 commit 562e839

File tree

16 files changed

+688
-599
lines changed

16 files changed

+688
-599
lines changed

Files/BaseLayout.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,11 +605,13 @@ protected async void Item_DragStarting(object sender, DragStartingEventArgs e)
605605
}
606606
else if (item.PrimaryItemAttribute == StorageItemTypes.File)
607607
{
608-
selectedStorageItems.Add(await ParentShellPageInstance.FilesystemViewModel.GetFileFromPathAsync(item.ItemPath));
608+
await ParentShellPageInstance.FilesystemViewModel.GetFileFromPathAsync(item.ItemPath)
609+
.OnSuccess(t => selectedStorageItems.Add(t));
609610
}
610611
else if (item.PrimaryItemAttribute == StorageItemTypes.Folder)
611612
{
612-
selectedStorageItems.Add(await ParentShellPageInstance.FilesystemViewModel.GetFolderFromPathAsync(item.ItemPath));
613+
await ParentShellPageInstance.FilesystemViewModel.GetFolderFromPathAsync(item.ItemPath)
614+
.OnSuccess(t => selectedStorageItems.Add(t));
613615
}
614616
}
615617

Files/Commands/Delete.cs

Lines changed: 88 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -44,73 +44,72 @@ public async void DeleteItemWithStatus(StorageDeleteOption deleteOption)
4444
StatusBanner.StatusBannerOperation.Recycle);
4545
}
4646

47-
try
48-
{
49-
Stopwatch sw = new Stopwatch();
50-
sw.Start();
51-
52-
await DeleteItem(deleteOption, AppInstance, bannerResult.Progress);
53-
bannerResult.Remove();
54-
55-
sw.Stop();
47+
Stopwatch sw = new Stopwatch();
48+
sw.Start();
5649

57-
if (sw.Elapsed.TotalSeconds >= 10)
50+
var res = await DeleteItem(deleteOption, AppInstance, bannerResult.Progress);
51+
bannerResult.Remove();
52+
sw.Stop();
53+
if (!res)
54+
{
55+
if (res.ErrorCode == FilesystemErrorCode.ERROR_UNAUTHORIZED)
5856
{
59-
if (deleteOption == StorageDeleteOption.PermanentDelete)
60-
{
61-
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostBanner(
62-
"Deletion Complete",
63-
"The operation has completed.",
57+
bannerResult.Remove();
58+
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostBanner(
59+
"AccessDeniedDeleteDialog/Title".GetLocalized(),
60+
"AccessDeniedDeleteDialog/Text".GetLocalized(),
6461
0,
65-
StatusBanner.StatusBannerSeverity.Success,
62+
StatusBanner.StatusBannerSeverity.Error,
6663
StatusBanner.StatusBannerOperation.Delete);
67-
}
68-
else
69-
{
70-
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostBanner(
71-
"Recycle Complete",
72-
"The operation has completed.",
64+
}
65+
else if (res.ErrorCode == FilesystemErrorCode.ERROR_NOTFOUND)
66+
{
67+
bannerResult.Remove();
68+
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostBanner(
69+
"FileNotFoundDialog/Title".GetLocalized(),
70+
"FileNotFoundDialog/Text".GetLocalized(),
7371
0,
74-
StatusBanner.StatusBannerSeverity.Success,
75-
StatusBanner.StatusBannerOperation.Recycle);
76-
}
72+
StatusBanner.StatusBannerSeverity.Error,
73+
StatusBanner.StatusBannerOperation.Delete);
74+
}
75+
else if (res.ErrorCode == FilesystemErrorCode.ERROR_INUSE)
76+
{
77+
bannerResult.Remove();
78+
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostActionBanner(
79+
"FileInUseDeleteDialog/Title".GetLocalized(),
80+
"FileInUseDeleteDialog/Text".GetLocalized(),
81+
"FileInUseDeleteDialog/PrimaryButtonText".GetLocalized(),
82+
"FileInUseDeleteDialog/SecondaryButtonText".GetLocalized(), () => { DeleteItemWithStatus(deleteOption); });
7783
}
78-
79-
AppInstance.NavigationToolbar.CanGoForward = false;
80-
}
81-
catch (UnauthorizedAccessException)
82-
{
83-
bannerResult.Remove();
84-
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostBanner(
85-
"AccessDeniedDeleteDialog/Title".GetLocalized(),
86-
"AccessDeniedDeleteDialog/Text".GetLocalized(),
87-
0,
88-
StatusBanner.StatusBannerSeverity.Error,
89-
StatusBanner.StatusBannerOperation.Delete);
9084
}
91-
catch (FileNotFoundException)
85+
else if (sw.Elapsed.TotalSeconds >= 10)
9286
{
93-
bannerResult.Remove();
94-
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostBanner(
95-
"FileNotFoundDialog/Title".GetLocalized(),
96-
"FileNotFoundDialog/Text".GetLocalized(),
87+
if (deleteOption == StorageDeleteOption.PermanentDelete)
88+
{
89+
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostBanner(
90+
"Deletion Complete",
91+
"The operation has completed.",
9792
0,
98-
StatusBanner.StatusBannerSeverity.Error,
93+
StatusBanner.StatusBannerSeverity.Success,
9994
StatusBanner.StatusBannerOperation.Delete);
95+
}
96+
else
97+
{
98+
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostBanner(
99+
"Recycle Complete",
100+
"The operation has completed.",
101+
0,
102+
StatusBanner.StatusBannerSeverity.Success,
103+
StatusBanner.StatusBannerOperation.Recycle);
104+
}
100105
}
101-
catch (IOException)
102-
{
103-
bannerResult.Remove();
104-
AppInstance.BottomStatusStripControl.OngoingTasksControl.PostActionBanner(
105-
"FileInUseDeleteDialog/Title".GetLocalized(),
106-
"FileInUseDeleteDialog/Text".GetLocalized(),
107-
"FileInUseDeleteDialog/PrimaryButtonText".GetLocalized(),
108-
"FileInUseDeleteDialog/SecondaryButtonText".GetLocalized(), () => { DeleteItemWithStatus(deleteOption); });
109-
}
106+
107+
AppInstance.NavigationToolbar.CanGoForward = false;
110108
}
111109

112-
private async Task DeleteItem(StorageDeleteOption deleteOption, IShellPage AppInstance, IProgress<uint> progress)
110+
private async Task<FilesystemResult> DeleteItem(StorageDeleteOption deleteOption, IShellPage AppInstance, IProgress<uint> progress)
113111
{
112+
var deleted = (FilesystemResult)false;
114113
var deleteFromRecycleBin = AppInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath);
115114

116115
List<ListedItem> selectedItems = new List<ListedItem>();
@@ -126,7 +125,7 @@ private async Task DeleteItem(StorageDeleteOption deleteOption, IShellPage AppIn
126125

127126
if (dialog.Result != MyResult.Delete) //delete selected item(s) if the result is yes
128127
{
129-
return; //return if the result isn't delete
128+
return (FilesystemResult)true; //return if the result isn't delete
130129
}
131130
deleteOption = dialog.PermanentlyDelete;
132131
}
@@ -137,31 +136,29 @@ private async Task DeleteItem(StorageDeleteOption deleteOption, IShellPage AppIn
137136
uint progressValue = (uint)(itemsDeleted * 100.0 / selectedItems.Count);
138137
if (selectedItems.Count > 3) { progress.Report((uint)progressValue); }
139138

140-
IStorageItem item;
141-
try
139+
if (storItem.PrimaryItemAttribute == StorageItemTypes.File)
142140
{
143-
if (storItem.PrimaryItemAttribute == StorageItemTypes.File)
144-
{
145-
item = await AppInstance.FilesystemViewModel.GetFileFromPathAsync(storItem.ItemPath);
146-
}
147-
else
148-
{
149-
item = await AppInstance.FilesystemViewModel.GetFolderFromPathAsync(storItem.ItemPath);
150-
}
151-
152-
await item.DeleteAsync(deleteOption);
141+
deleted = await AppInstance.FilesystemViewModel.GetFileFromPathAsync(storItem.ItemPath)
142+
.OnSuccess(t => t.DeleteAsync(deleteOption).AsTask());
143+
}
144+
else
145+
{
146+
deleted = await AppInstance.FilesystemViewModel.GetFolderFromPathAsync(storItem.ItemPath)
147+
.OnSuccess(t => t.DeleteAsync(deleteOption).AsTask());
153148
}
154-
catch (UnauthorizedAccessException)
149+
150+
if (deleted.ErrorCode == FilesystemErrorCode.ERROR_UNAUTHORIZED)
155151
{
156152
if (deleteOption == StorageDeleteOption.Default)
157153
{
158154
// Try again with fulltrust process
159155
if (AppInstance.FilesystemViewModel.Connection != null)
160156
{
161-
var result = await AppInstance.FilesystemViewModel.Connection.SendMessageAsync(new ValueSet() {
162-
{ "Arguments", "FileOperation" },
163-
{ "fileop", "MoveToBin" },
164-
{ "filepath", storItem.ItemPath } });
157+
var response = await AppInstance.FilesystemViewModel.Connection.SendMessageAsync(new ValueSet() {
158+
{ "Arguments", "FileOperation" },
159+
{ "fileop", "MoveToBin" },
160+
{ "filepath", storItem.ItemPath } });
161+
deleted = (FilesystemResult)(response.Status == Windows.ApplicationModel.AppService.AppServiceResponseStatus.Success);
165162
}
166163
}
167164
else
@@ -171,33 +168,38 @@ private async Task DeleteItem(StorageDeleteOption deleteOption, IShellPage AppIn
171168
{
172169
Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());
173170
}
171+
else
172+
{
173+
deleted = (FilesystemResult)true;
174+
}
174175
}
175176
}
176-
catch (FileLoadException)
177+
else if (deleted.ErrorCode == FilesystemErrorCode.ERROR_INUSE)
177178
{
178-
// try again
179-
if (storItem.PrimaryItemAttribute == StorageItemTypes.File)
180-
{
181-
item = await AppInstance.FilesystemViewModel.GetFileFromPathAsync(storItem.ItemPath);
182-
}
183-
else
184-
{
185-
item = await AppInstance.FilesystemViewModel.GetFolderFromPathAsync(storItem.ItemPath);
186-
}
187-
188-
await item.DeleteAsync(deleteOption);
179+
// TODO: retry or show dialog
180+
await DialogDisplayHelper.ShowDialog("FileInUseDeleteDialog/Title".GetLocalized(), "FileInUseDeleteDialog/Text".GetLocalized());
189181
}
190182

191183
if (deleteFromRecycleBin)
192184
{
193185
// Recycle bin also stores a file starting with $I for each item
194186
var iFilePath = Path.Combine(Path.GetDirectoryName(storItem.ItemPath), Path.GetFileName(storItem.ItemPath).Replace("$R", "$I"));
195-
await (await AppInstance.FilesystemViewModel.GetFileFromPathAsync(iFilePath)).DeleteAsync(StorageDeleteOption.PermanentDelete);
187+
await AppInstance.FilesystemViewModel.GetFileFromPathAsync(iFilePath)
188+
.OnSuccess(t => t.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask());
196189
}
197190

198-
await AppInstance.FilesystemViewModel.RemoveFileOrFolder(storItem);
199-
itemsDeleted++;
191+
if (deleted)
192+
{
193+
await AppInstance.FilesystemViewModel.RemoveFileOrFolder(storItem);
194+
itemsDeleted++;
195+
}
196+
else
197+
{
198+
// Stop at first error
199+
return deleted;
200+
}
200201
}
202+
return (FilesystemResult)true;
201203
}
202204
}
203205
}

0 commit comments

Comments
 (0)