Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ You can also use the preview version alongside the stable release to get early a
<img src="./assets/StoreBadge-light.png" height="80" /></picture></a>
&ensp;
<!-- Classic Installer Badge -->
<a style="text-decoration:none" href="https://files.community/appinstallers/Files.stable.appinstaller">
<a style="text-decoration:none" href="https://files.community/download">
<picture>
<source media="(prefers-color-scheme: light)" srcset="./assets/ClassicInstallerBadge-dark.png" height="80" />
<img src="./assets/ClassicInstallerBadge-light.png" height="80" /></picture></a>
Expand Down
6 changes: 3 additions & 3 deletions src/Files.App/Actions/FileSystem/FlattenFolderAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private void FlattenFolder(string path)
}
catch (Exception ex)
{
App.Logger.LogWarning(ex.Message, $"Folder '{folderName}' already exists in the destination folder.");
App.Logger.LogWarning(ex, $"Folder '{LogPathHelper.RedactPath(folderName)}' already exists in the destination folder.");
}
}

Expand All @@ -106,7 +106,7 @@ private void FlattenFolder(string path)
}
catch (Exception ex)
{
App.Logger.LogWarning(ex.Message, $"Failed to move file '{fileName}'.");
App.Logger.LogWarning(ex, $"Failed to move file '{LogPathHelper.RedactPath(fileName)}'.");
}
}

Expand All @@ -118,7 +118,7 @@ private void FlattenFolder(string path)
}
catch (Exception ex)
{
App.Logger.LogWarning(ex.Message, $"Failed to delete folder '{path}'.");
App.Logger.LogWarning(ex, $"Failed to delete folder '{LogPathHelper.RedactPath(path)}'.");
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Files.App/Data/Items/ExpandableSidebarItemBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private void StartWatchingSubfolders()
// FileSystemWatcher ctor throws ArgumentException for invalid paths, UnauthorizedAccessException for protected roots; either way fall back to no live updates for this subtree.
catch (Exception ex)
{
App.Logger?.LogDebug(ex, "Sidebar subfolder watcher start failed for {Path}", ExpansionPath);
App.Logger?.LogDebug(ex, "Sidebar subfolder watcher start failed for {Path}", LogPathHelper.RedactPath(ExpansionPath));
subfolderWatcher?.Dispose();
subfolderWatcher = null;
}
Expand Down Expand Up @@ -214,7 +214,7 @@ private async Task ResyncSubfoldersAsync()
// EnumerateSubfolders can throw UnauthorizedAccessException / IOException if the folder is in a bad state mid-resync; treat as "no change visible right now" rather than tearing down ChildItems.
catch (Exception ex)
{
App.Logger?.LogDebug(ex, "Sidebar subfolder resync enumeration failed for {Path}", ExpansionPath);
App.Logger?.LogDebug(ex, "Sidebar subfolder resync enumeration failed for {Path}", LogPathHelper.RedactPath(ExpansionPath));
return;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Files.App/Data/Items/LocationItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ await dispatcher.EnqueueOrInvokeAsync(async () =>
// FolderHelpers.EnumerateSubfolders / FileThumbnailHelper can throw UnauthorizedAccessException, IOException, or COMException on inaccessible / missing paths. Still run onLoaded on the dispatcher so the caller can clear HasUnrealizedChildren and mark childrenLoaded — otherwise the chevron stays and every subsequent click replays the failing enumeration.
catch (Exception ex)
{
App.Logger?.LogDebug(ex, "Sidebar subfolder enumeration failed for {Path}", enumerationPath);
App.Logger?.LogDebug(ex, "Sidebar subfolder enumeration failed for {Path}", LogPathHelper.RedactPath(enumerationPath));
await (MainWindow.Instance?.DispatcherQueue).EnqueueOrInvokeAsync(onLoaded);
}
}
Expand Down Expand Up @@ -194,7 +194,7 @@ internal static async Task UpgradeIconsAsync(List<LocationItem> children, byte[]
// FileThumbnailHelper.GetIconAsync can throw COMException / UnauthorizedAccessException on inaccessible paths; keep the shared generic icon.
catch (Exception ex)
{
App.Logger?.LogDebug(ex, "LocationItem: real icon load failed for {Path}", path);
App.Logger?.LogDebug(ex, "LocationItem: real icon load failed for {Path}", LogPathHelper.RedactPath(path));
continue;
}

Expand All @@ -212,7 +212,7 @@ await dispatcher.EnqueueOrInvokeAsync(async () =>
item.Icon = bmp;
}
// BitmapImage.SetSourceAsync throws on corrupt bytes; keep the generic icon.
catch (Exception ex) { App.Logger?.LogDebug(ex, "LocationItem: real icon decode failed for {Path}", path); }
catch (Exception ex) { App.Logger?.LogDebug(ex, "LocationItem: real icon decode failed for {Path}", LogPathHelper.RedactPath(path)); }
}, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Files.App/Data/Models/CompressArchiveModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ await Task.Run(() =>
if (skippedItems.Count > 0)
{
var logger = Ioc.Default.GetRequiredService<ILogger<App>>();
logger?.LogWarning($"Skipped {skippedItems.Count} item(s) that could not be archived to {ArchivePath}: {string.Join(", ", skippedItems)}");
logger?.LogWarning($"Skipped {skippedItems.Count} item(s) that could not be archived to {LogPathHelper.RedactPath(ArchivePath)}: {string.Join(", ", skippedItems.Select(LogPathHelper.RedactPath))}");

// Ask the user whether to skip the items or cancel the operation, see #16240
var dialogService = Ioc.Default.GetRequiredService<IDialogService>();
Expand Down Expand Up @@ -324,7 +324,7 @@ static void AddArchiveEntry(IDictionary<string, string> entries, string name, st
catch (Exception ex)
{
var logger = Ioc.Default.GetRequiredService<ILogger<App>>();
logger?.LogWarning(ex, $"Error compressing folder: {ArchivePath}");
logger?.LogWarning(ex, $"Error compressing folder: {LogPathHelper.RedactPath(ArchivePath)}");

cts.Cancel();

Expand Down
66 changes: 66 additions & 0 deletions src/Files.App/Helpers/Application/AppLifecycleHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,75 @@ public static void ConfigureSentry()
options.Environment = AppEnvironment == AppEnvironment.StorePreview || AppEnvironment == AppEnvironment.SideloadPreview ? "preview" : "production";

options.DisableWinUiUnhandledExceptionIntegration();

options.SetBeforeSend(sentryEvent =>
{
if (sentryEvent.Message is { } message)
{
message.Message = SanitizeSentryText(message.Message);
message.Formatted = SanitizeSentryText(message.Formatted);
}

if (sentryEvent.SentryExceptions is { } sentryExceptions)
{
foreach (var sentryException in sentryExceptions)
{
sentryException.Value = SanitizeSentryText(sentryException.Value);

if (sentryException.Stacktrace?.Frames is { } frames)
{
foreach (var frame in frames)
{
frame.FileName = LogPathHelper.RedactUserName(frame.FileName);
frame.AbsolutePath = LogPathHelper.RedactUserName(frame.AbsolutePath);
}
}
}
}

foreach (var key in sentryEvent.Extra.Keys.ToList())
{
if (sentryEvent.Extra[key] is string text)
sentryEvent.SetExtra(key, SanitizeSentryText(text) ?? string.Empty);
}

return sentryEvent;
});

options.SetBeforeBreadcrumb(breadcrumb =>
{
var message = SanitizeSentryText(breadcrumb.Message);

Dictionary<string, string>? sanitizedData = null;
if (breadcrumb.Data is { } data)
{
foreach (var (key, value) in data)
{
var sanitizedValue = SanitizeSentryText(value);
if (sanitizedValue != value)
{
sanitizedData ??= new(data);
sanitizedData[key] = sanitizedValue ?? string.Empty;
}
}
}

if (message == breadcrumb.Message && sanitizedData is null)
return breadcrumb;

return new Breadcrumb(message!, breadcrumb.Type!, sanitizedData ?? breadcrumb.Data, breadcrumb.Category, breadcrumb.Level);
});
});
}

/// <summary>
/// Scrubs user names and file system paths from text before it is attached to a Sentry event.
/// </summary>
private static string? SanitizeSentryText(string? text)
{
return text is null ? null : LogPathHelper.SanitizeMessage(text);
}

/// <summary>
/// Configures DI (dependency injection) container.
/// </summary>
Expand Down
34 changes: 0 additions & 34 deletions src/Files.App/Helpers/LogPathHelper.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Files.App/Helpers/PathNormalization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static string GetPathRoot(string? path)
}
catch (Exception ex) when (ex is UriFormatException || ex is ArgumentException)
{
App.Logger.LogDebug(ex, path);
App.Logger.LogDebug(ex, LogPathHelper.RedactPath(path));
return path;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Services/Git/LibGit2Service.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ await DoGitOperationAsync<GitOperationResult>(() =>
catch (Exception ex)
{
// An unreachable remote (e.g. a deleted fork answering 401) must not prevent fetching the remaining remotes
_logger.LogWarning(ex, "Failed to fetch remote {RemoteName} in {RepositoryPath}", remote.Name, repositoryPath);
_logger.LogWarning(ex, "Failed to fetch remote {RemoteName} in {RepositoryPath}", remote.Name, LogPathHelper.RedactPath(repositoryPath));

if (IsAuthorizationException(ex))
result = GitOperationResult.AuthorizationError;
Expand Down
4 changes: 2 additions & 2 deletions src/Files.App/Services/Windows/WindowsDialogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
// Handle shell item creation failure gracefully
if (hr.Failed)
{
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);
App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", defaultFolder, hr.Value);
// Continue without setting default folder rather than failing completely
}
else
Expand Down Expand Up @@ -159,7 +159,7 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
// Handle shell item creation failure gracefully
if (hr.Failed)
{
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);
App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", defaultFolder, hr.Value);
// Continue without setting default folder rather than failing completely
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Utils/Cloud/CloudDrivesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static async Task UpdateDrivesAsync()

foreach (var provider in providers)
{
_logger?.LogInformation($"Adding cloud provider \"{provider.Name}\" mapped to {provider.SyncFolder}");
_logger?.LogInformation($"Adding cloud provider {provider.ID} mapped to {LogPathHelper.RedactUserName(provider.SyncFolder)}");

var cloudProviderItem = new DriveItem()
{
Expand Down
4 changes: 2 additions & 2 deletions src/Files.App/Utils/Cloud/Detector/DropBoxCloudDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ protected override async IAsyncEnumerable<ICloudProvider> GetProviders()
if (File.Exists(websiteJsonPath))
{
infoJsonPath = websiteJsonPath;
App.Logger.LogInformation("Dropbox: Found website version at {Path}", websiteJsonPath);
App.Logger.LogInformation("Dropbox: Found website version at {Path}", LogPathHelper.RedactUserName(websiteJsonPath));
}
else
{
Expand Down Expand Up @@ -51,7 +51,7 @@ protected override async IAsyncEnumerable<ICloudProvider> GetProviders()
if (newestInfoJsonPath is not null)
{
infoJsonPath = newestInfoJsonPath;
App.Logger.LogInformation("Dropbox: Found Store version at {Path} (last modified: {Timestamp})", newestInfoJsonPath, newestTimestamp);
App.Logger.LogInformation("Dropbox: Found Store version at {Path} (last modified: {Timestamp})", LogPathHelper.RedactUserName(newestInfoJsonPath), newestTimestamp);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
var folderResult = await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(path).AsTask());
if (!folderResult)
{
_logger.LogWarning($"Could not access Google Drive path as local storage: {path}");
_logger.LogWarning($"Could not access Google Drive path as local storage: {LogPathHelper.RedactUserName(path)}");
continue;
}

Expand Down Expand Up @@ -98,7 +98,7 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
var folderResult = await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(path).AsTask());
if (!folderResult)
{
_logger.LogWarning($"Could not access Google Drive path as local storage: {path}");
_logger.LogWarning($"Could not access Google Drive path as local storage: {LogPathHelper.RedactUserName(path)}");
continue;
}

Expand Down Expand Up @@ -269,7 +269,7 @@ private static bool ValidatePath(string path)
{
if (Directory.Exists(path))
return true;
_logger.LogWarning($"Invalid path: {path}");
_logger.LogWarning($"Invalid path: {LogPathHelper.RedactUserName(path)}");
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Utils/Global/WindowsStorageDeviceWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private async void Watcher_Added(DeviceWatcher sender, DeviceInformation args)
}
catch (Exception ex) when (ex is ArgumentException or UnauthorizedAccessException or COMException)
{
App.Logger.LogWarning($"{ex.GetType()}: Attempting to add the device, {args.Name},"
App.Logger.LogWarning($"{ex.GetType()}: Attempting to add the device, {LogPathHelper.RedactPath(args.Name)},"
+ $" failed at the StorageFolder initialization step. This device will be ignored. Device ID: {deviceId}");
return;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Files.App/Utils/Library/LibraryManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,22 +387,22 @@ private void OnLibraryChanged(WatcherChangeTypes changeType, string? oldPath, st
{
if (newPath is null)
{
App.Logger.LogWarning($"Failed to open library after {changeType}: {newPath}");
App.Logger.LogWarning($"Failed to open library after {changeType}: {LogPathHelper.RedactPath(newPath)}");
return;
}

using var libraryFile = SafetyExtensions.IgnoreExceptions(() => ShellItem.Open(newPath));
var library = SafetyExtensions.IgnoreExceptions(() => new ShellLibraryEx(libraryFile!.IShellItem, true));
if (library is null)
{
App.Logger.LogWarning($"Failed to open library after {changeType}: {newPath}");
App.Logger.LogWarning($"Failed to open library after {changeType}: {LogPathHelper.RedactPath(newPath)}");
return;
}

var library1 = SafetyExtensions.IgnoreExceptions(() => ShellFolderExtensions.GetShellLibraryItem(library, newPath));
if (library1 is null)
{
App.Logger.LogWarning($"Failed to open library after {changeType}: {newPath}");
App.Logger.LogWarning($"Failed to open library after {changeType}: {LogPathHelper.RedactPath(newPath)}");
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Utils/Shell/LaunchHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ private static async Task<bool> HandleApplicationLaunch(string application, stri
catch (Exception ex)
{
// Generic error, log
App.Logger.LogWarning(ex, $"Error launching: {application}");
App.Logger.LogWarning(ex, $"Error launching: {LogPathHelper.RedactPath(application)}");
return false;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Files.App/Utils/Storage/Helpers/FontFileHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static class FontFileHelper
}
catch (Exception ex)
{
App.Logger.LogError(ex, $"Exception while getting WinRT thumbnail for {fontPath}.");
App.Logger.LogError(ex, $"Exception while getting WinRT thumbnail for {LogPathHelper.RedactPath(fontPath)}.");
return null;
}
finally
Expand Down Expand Up @@ -91,7 +91,7 @@ public static class FontFileHelper
}
catch (Exception ex)
{
App.Logger.LogError(ex, $"Exception while generating font thumbnail for {fontPath}.");
App.Logger.LogError(ex, $"Exception while generating font thumbnail for {LogPathHelper.RedactPath(fontPath)}.");
return null;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Files.App/Utils/Storage/Operations/FilesystemHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,8 @@ public static bool IsValidForFilename(string name)
if (!collisions.TryAdd(itemPathOrName, FileNameConflictResolveOptionType.GenerateNewName))
{
// Something strange happened, log
App.Logger.LogWarning($"Duplicate key when resolving conflicts: {itemPathOrName}, {src.Name}\n" +
$"Source: {string.Join(", ", source.Select(x => string.IsNullOrEmpty(x.Path) ? x.Name : x.Path))}");
App.Logger.LogWarning($"Duplicate key when resolving conflicts: {LogPathHelper.RedactPath(itemPathOrName)}, {LogPathHelper.RedactPath(src.Name)}\n" +
$"Source: {string.Join(", ", source.Select(x => LogPathHelper.RedactPath(string.IsNullOrEmpty(x.Path) ? x.Name : x.Path)))}");
}

// Assume GenerateNewName when source and destination are the same
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Utils/Storage/Search/FolderSearch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ private TagQueryExpression ParseTagQuery(string query)

if (string.IsNullOrEmpty(tagValue))
{
logger.LogWarning("Failed to parse tag query: {Query}", andPart);
logger.LogWarning("Failed to parse tag query.");
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public async override Task GetSpecialPropertiesAsync()
}
catch (Exception e)
{
App.Logger.LogWarning(e, "Failed to get sync root quota for path: {Path}", Drive.Path);
App.Logger.LogWarning(e, "Failed to get sync root quota for path: {Path}", LogPathHelper.RedactPath(Drive.Path));
}

try
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/ViewModels/ShellViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3263,7 +3263,7 @@ public void Dispose()
semaphoreCTS.Cancel();
searchCTS?.Cancel();
updateTagGroupCTS?.Cancel();
App.Logger.LogInformation($"ShellViewModel.Dispose: CurrentFolder={LogPathHelper.GetPathIdentifier(CurrentFolder?.ItemPath)}");
App.Logger.LogInformation($"ShellViewModel.Dispose: CurrentFolder={LogPathHelper.RedactPath(CurrentFolder?.ItemPath)}");

StorageTrashBinService.Watcher.ItemAdded -= RecycleBinItemCreatedAsync;
StorageTrashBinService.Watcher.ItemDeleted -= RecycleBinItemDeletedAsync;
Expand Down
Loading
Loading