Skip to content

Commit b7dd8cb

Browse files
Code Quality: Handle COM and other exceptions in file dialog services (#17448)
Co-authored-by: seer-by-sentry[bot] <157164994+seer-by-sentry[bot]@users.noreply.github.com>
1 parent 907c392 commit b7dd8cb

File tree

1 file changed

+68
-18
lines changed

1 file changed

+68
-18
lines changed

src/Files.App/Services/Windows/WindowsDialogService.cs

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
2323
try
2424
{
2525
using ComPtr<IFileOpenDialog> pDialog = default;
26-
HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileOpenDialog, null, CLSCTX.CLSCTX_INPROC_SERVER).ThrowOnFailure();
26+
HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileOpenDialog, null, CLSCTX.CLSCTX_INPROC_SERVER);
27+
28+
// Handle COM creation failure gracefully
29+
if (hr.Failed)
30+
{
31+
App.Logger.LogError("Failed to create IFileOpenDialog COM object. HRESULT: 0x{0:X8}", hr.Value);
32+
return false;
33+
}
2734

2835
if (filters.Length is not 0 && filters.Length % 2 is 0)
2936
{
@@ -52,24 +59,38 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
5259
pszDefaultFolderPath,
5360
null,
5461
IID.IID_IShellItem,
55-
(void**)pDefaultFolderShellItem.GetAddressOf())
56-
.ThrowOnFailure();
62+
(void**)pDefaultFolderShellItem.GetAddressOf());
63+
64+
// Handle shell item creation failure gracefully
65+
if (hr.Failed)
66+
{
67+
App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", Environment.GetFolderPath(defaultFolder), hr.Value);
68+
// Continue without setting default folder rather than failing completely
69+
}
5770
}
5871

5972
// Folder picker
6073
if (pickFoldersOnly)
6174
pDialog.Get()->SetOptions(FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS);
6275

63-
// Set the default folder to open in the dialog
64-
pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
65-
pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
76+
// Set the default folder to open in the dialog (only if creation succeeded)
77+
if (pDefaultFolderShellItem.Get() is not null)
78+
{
79+
pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
80+
pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
81+
}
6682

6783
// Show the dialog
6884
hr = pDialog.Get()->Show(new HWND(hWnd));
6985
if (hr.Value == unchecked((int)0x800704C7)) // HRESULT_FROM_WIN32(ERROR_CANCELLED)
7086
return false;
7187

72-
hr.ThrowOnFailure();
88+
// Handle dialog show failure gracefully
89+
if (hr.Failed)
90+
{
91+
App.Logger.LogError("Failed to show FileSaveDialog. HRESULT: 0x{0:X8}", hr.Value);
92+
return false;
93+
}
7394

7495
// Get the file that user chose
7596
using ComPtr<IShellItem> pResultShellItem = default;
@@ -81,10 +102,14 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
81102

82103
return true;
83104
}
105+
catch (COMException comEx)
106+
{
107+
App.Logger.LogError(comEx, "COM failure while opening FileOpenDialog. HRESULT: 0x{0:X8}", comEx.HResult);
108+
return false;
109+
}
84110
catch (Exception ex)
85111
{
86-
App.Logger.LogError(ex, "Failed to open FileOpenDialog.");
87-
112+
App.Logger.LogError(ex, "Unexpected error while opening FileOpenDialog.");
88113
return false;
89114
}
90115
}
@@ -97,7 +122,14 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
97122
try
98123
{
99124
using ComPtr<IFileSaveDialog> pDialog = default;
100-
HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileSaveDialog, null, CLSCTX.CLSCTX_INPROC_SERVER).ThrowOnFailure();
125+
HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileSaveDialog, null, CLSCTX.CLSCTX_INPROC_SERVER);
126+
127+
// Handle COM creation failure gracefully
128+
if (hr.Failed)
129+
{
130+
App.Logger.LogError("Failed to create IFileSaveDialog COM object. HRESULT: 0x{0:X8}", hr.Value);
131+
return false;
132+
}
101133

102134
if (filters.Length is not 0 && filters.Length % 2 is 0)
103135
{
@@ -126,24 +158,38 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
126158
pszDefaultFolderPath,
127159
null,
128160
IID.IID_IShellItem,
129-
(void**)pDefaultFolderShellItem.GetAddressOf())
130-
.ThrowOnFailure();
161+
(void**)pDefaultFolderShellItem.GetAddressOf());
162+
163+
// Handle shell item creation failure gracefully
164+
if (hr.Failed)
165+
{
166+
App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", Environment.GetFolderPath(defaultFolder), hr.Value);
167+
// Continue without setting default folder rather than failing completely
168+
}
131169
}
132170

133171
// Folder picker
134172
if (pickFoldersOnly)
135173
pDialog.Get()->SetOptions(FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS);
136174

137-
// Set the default folder to open in the dialog
138-
pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
139-
pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
175+
// Set the default folder to open in the dialog (only if creation succeeded)
176+
if (pDefaultFolderShellItem.Get() is not null)
177+
{
178+
pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
179+
pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
180+
}
140181

141182
// Show the dialog
142183
hr = pDialog.Get()->Show(new HWND(hWnd));
143184
if (hr.Value == unchecked((int)0x800704C7)) // HRESULT_FROM_WIN32(ERROR_CANCELLED)
144185
return false;
145186

146-
hr.ThrowOnFailure();
187+
// Handle dialog show failure gracefully
188+
if (hr.Failed)
189+
{
190+
App.Logger.LogError("Failed to show FileSaveDialog. HRESULT: 0x{0:X8}", hr.Value);
191+
return false;
192+
}
147193

148194
// Get the file that user chose
149195
using ComPtr<IShellItem> pResultShellItem = default;
@@ -155,10 +201,14 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
155201

156202
return true;
157203
}
204+
catch (COMException comEx)
205+
{
206+
App.Logger.LogError(comEx, "COM failure while opening FileSaveDialog. HRESULT: 0x{0:X8}", comEx.HResult);
207+
return false;
208+
}
158209
catch (Exception ex)
159210
{
160-
App.Logger.LogError(ex, "Failed to open FileSaveDialog.");
161-
211+
App.Logger.LogError(ex, "Unexpected error while opening FileSaveDialog.");
162212
return false;
163213
}
164214
}

0 commit comments

Comments
 (0)