diff --git a/Source/ApplicationServices/LibraryCommands.cs b/Source/ApplicationServices/LibraryCommands.cs index f0c6e881..b18e05c9 100644 --- a/Source/ApplicationServices/LibraryCommands.cs +++ b/Source/ApplicationServices/LibraryCommands.cs @@ -229,7 +229,7 @@ namespace ApplicationServices { var tasks = new List>>(); - await using LogArchiver archiver + await using LogArchiver archiver = Log.Logger.IsDebugEnabled() ? new LogArchiver(System.IO.Path.Combine(Configuration.Instance.LibationFiles, "LibraryScans.zip")) : default; @@ -238,16 +238,24 @@ namespace ApplicationServices foreach (var account in accounts) { - // get APIs in serial b/c of logins. do NOT move inside of parallel (Task.WhenAll) - var apiExtended = await apiExtendedfunc(account); + try + { + // get APIs in serial b/c of logins. do NOT move inside of parallel (Task.WhenAll) + var apiExtended = await apiExtendedfunc(account); - // add scanAccountAsync as a TASK: do not await - tasks.Add(scanAccountAsync(apiExtended, account, libraryOptions, archiver)); + // add scanAccountAsync as a TASK: do not await + tasks.Add(scanAccountAsync(apiExtended, account, libraryOptions, archiver)); + } + catch(Exception ex) + { + //Catch to allow other accounts to continue scanning. + Log.Logger.Error(ex, "Failed to scan account"); + } } // import library in parallel - var arrayOfLists = await Task.WhenAll(tasks); - var importItems = arrayOfLists.SelectMany(a => a).ToList(); + var arrayOfLists = await Task.WhenAll(tasks); + var importItems = arrayOfLists.SelectMany(a => a).ToList(); return importItems; } diff --git a/Source/LibationAvalonia/Dialogs/Login/AvaloniaLoginChoiceEager.cs b/Source/LibationAvalonia/Dialogs/Login/AvaloniaLoginChoiceEager.cs index a812c18c..1e0373b1 100644 --- a/Source/LibationAvalonia/Dialogs/Login/AvaloniaLoginChoiceEager.cs +++ b/Source/LibationAvalonia/Dialogs/Login/AvaloniaLoginChoiceEager.cs @@ -25,7 +25,7 @@ namespace LibationAvalonia.Dialogs.Login { var dialog = new LoginChoiceEagerDialog(_account); - if (await dialog.ShowDialogAsync() is not DialogResult.OK) + if (await dialog.ShowDialogAsync() is not DialogResult.OK || string.IsNullOrWhiteSpace(dialog.Password)) return null; switch (dialog.LoginMethod) diff --git a/Source/LibationAvalonia/Dialogs/Login/LoginChoiceEagerDialog.axaml.cs b/Source/LibationAvalonia/Dialogs/Login/LoginChoiceEagerDialog.axaml.cs index c62c53de..a2d4311d 100644 --- a/Source/LibationAvalonia/Dialogs/Login/LoginChoiceEagerDialog.axaml.cs +++ b/Source/LibationAvalonia/Dialogs/Login/LoginChoiceEagerDialog.axaml.cs @@ -4,6 +4,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; using System.Linq; +using System.Threading.Tasks; namespace LibationAvalonia.Dialogs.Login { @@ -31,6 +32,17 @@ namespace LibationAvalonia.Dialogs.Login DataContext = this; } + protected override async Task SaveAndCloseAsync() + { + if (string.IsNullOrWhiteSpace(Password)) + { + await MessageBox.Show(this, "Please enter your password"); + return; + } + + await base.SaveAndCloseAsync(); + } + public async void ExternalLoginLink_Tapped(object sender, Avalonia.Input.TappedEventArgs e) { LoginMethod = LoginMethod.External; diff --git a/Source/LibationAvalonia/ViewModels/ProductsDisplayViewModel.cs b/Source/LibationAvalonia/ViewModels/ProductsDisplayViewModel.cs index a6c4bac6..e35cc9c8 100644 --- a/Source/LibationAvalonia/ViewModels/ProductsDisplayViewModel.cs +++ b/Source/LibationAvalonia/ViewModels/ProductsDisplayViewModel.cs @@ -427,6 +427,10 @@ namespace LibationAvalonia.ViewModels foreach (var r in removable) r.Remove = true; } + catch (OperationCanceledException) + { + Serilog.Log.Information("Audible login attempt cancelled by user"); + } catch (Exception ex) { await MessageBox.ShowAdminAlert( diff --git a/Source/LibationAvalonia/Views/MainWindow.ScanAuto.cs b/Source/LibationAvalonia/Views/MainWindow.ScanAuto.cs index f201e57f..7b9b33be 100644 --- a/Source/LibationAvalonia/Views/MainWindow.ScanAuto.cs +++ b/Source/LibationAvalonia/Views/MainWindow.ScanAuto.cs @@ -32,6 +32,10 @@ namespace LibationAvalonia.Views { await LibraryCommands.ImportAccountAsync(Dialogs.Login.AvaloniaLoginChoiceEager.ApiExtendedFunc, accounts); } + catch (OperationCanceledException) + { + Serilog.Log.Information("Audible login attempt cancelled by user"); + } catch (Exception ex) { Serilog.Log.Logger.Error(ex, "Error invoking auto-scan"); diff --git a/Source/LibationAvalonia/Views/MainWindow.ScanManual.cs b/Source/LibationAvalonia/Views/MainWindow.ScanManual.cs index a94984c4..1349d02f 100644 --- a/Source/LibationAvalonia/Views/MainWindow.ScanManual.cs +++ b/Source/LibationAvalonia/Views/MainWindow.ScanManual.cs @@ -69,6 +69,10 @@ namespace LibationAvalonia.Views if (Configuration.Instance.ShowImportedStats && newAdded > 0) await MessageBox.Show($"Total processed: {totalProcessed}\r\nNew: {newAdded}"); } + catch(OperationCanceledException) + { + Serilog.Log.Information("Audible login attempt cancelled by user"); + } catch (Exception ex) { await MessageBox.ShowAdminAlert( diff --git a/Source/LibationWinForms/Dialogs/Login/LoginChoiceEagerDialog.cs b/Source/LibationWinForms/Dialogs/Login/LoginChoiceEagerDialog.cs index e3c75906..b10055c2 100644 --- a/Source/LibationWinForms/Dialogs/Login/LoginChoiceEagerDialog.cs +++ b/Source/LibationWinForms/Dialogs/Login/LoginChoiceEagerDialog.cs @@ -37,6 +37,12 @@ namespace LibationWinForms.Dialogs.Login Email = accountId; Password = this.passwordTb.Text; + if (string.IsNullOrWhiteSpace(Password)) + { + MessageBox.Show("Please enter your password"); + return; + } + Serilog.Log.Logger.Information("Submit button clicked: {@DebugInfo}", new { email = Email?.ToMask(), passwordLength = Password.Length }); LoginMethod = AudibleApi.LoginMethod.Api; diff --git a/Source/LibationWinForms/Dialogs/Login/WinformLoginChoiceEager.cs b/Source/LibationWinForms/Dialogs/Login/WinformLoginChoiceEager.cs index 0543d80f..df313002 100644 --- a/Source/LibationWinForms/Dialogs/Login/WinformLoginChoiceEager.cs +++ b/Source/LibationWinForms/Dialogs/Login/WinformLoginChoiceEager.cs @@ -25,7 +25,7 @@ namespace LibationWinForms.Login { using var dialog = new LoginChoiceEagerDialog(_account); - if (!ShowDialog(dialog)) + if (!ShowDialog(dialog) || string.IsNullOrWhiteSpace(dialog.Password)) return null; switch (dialog.LoginMethod) diff --git a/Source/LibationWinForms/Form1.ScanAuto.cs b/Source/LibationWinForms/Form1.ScanAuto.cs index 079140e9..ca91c770 100644 --- a/Source/LibationWinForms/Form1.ScanAuto.cs +++ b/Source/LibationWinForms/Form1.ScanAuto.cs @@ -38,7 +38,11 @@ namespace LibationWinForms else await importAsync(); } - catch (Exception ex) + catch (OperationCanceledException) + { + Serilog.Log.Information("Audible login attempt cancelled by user"); + } + catch (Exception ex) { Serilog.Log.Logger.Error(ex, "Error invoking auto-scan"); } diff --git a/Source/LibationWinForms/Form1.ScanManual.cs b/Source/LibationWinForms/Form1.ScanManual.cs index b238cbd6..d745c6d2 100644 --- a/Source/LibationWinForms/Form1.ScanManual.cs +++ b/Source/LibationWinForms/Form1.ScanManual.cs @@ -80,6 +80,10 @@ namespace LibationWinForms if (Configuration.Instance.ShowImportedStats && newAdded > 0) MessageBox.Show($"Total processed: {totalProcessed}\r\nNew: {newAdded}"); } + catch (OperationCanceledException) + { + Serilog.Log.Information("Audible login attempt cancelled by user"); + } catch (Exception ex) { MessageBoxLib.ShowAdminAlert( diff --git a/Source/LibationWinForms/GridView/ProductsDisplay.cs b/Source/LibationWinForms/GridView/ProductsDisplay.cs index 2ad49a05..6196b6a6 100644 --- a/Source/LibationWinForms/GridView/ProductsDisplay.cs +++ b/Source/LibationWinForms/GridView/ProductsDisplay.cs @@ -288,6 +288,10 @@ namespace LibationWinForms.GridView productsGrid_RemovableCountChanged(this, null); } + catch (OperationCanceledException) + { + Serilog.Log.Information("Audible login attempt cancelled by user"); + } catch (Exception ex) { MessageBoxLib.ShowAdminAlert(