Global exception handling. Threadsafe MessageBoxAlertAdminDialog
This commit is contained in:
parent
5a80a0cc06
commit
114925ebce
@ -256,18 +256,21 @@ namespace AppScaffolding
|
|||||||
|
|
||||||
private static void logStartupState(Configuration config)
|
private static void logStartupState(Configuration config)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
var mode = "Debug";
|
||||||
|
#else
|
||||||
|
var mode = "Release";
|
||||||
|
#endif
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached)
|
||||||
|
mode += " (Debugger attached)";
|
||||||
|
|
||||||
// begin logging session with a form feed
|
// begin logging session with a form feed
|
||||||
Log.Logger.Information("\r\n\f");
|
Log.Logger.Information("\r\n\f");
|
||||||
Log.Logger.Information("Begin. {@DebugInfo}", new
|
Log.Logger.Information("Begin. {@DebugInfo}", new
|
||||||
{
|
{
|
||||||
AppName = EntryAssembly.GetName().Name,
|
AppName = EntryAssembly.GetName().Name,
|
||||||
Version = BuildVersion.ToString(),
|
Version = BuildVersion.ToString(),
|
||||||
#if DEBUG
|
Mode = mode,
|
||||||
Mode = "Debug",
|
|
||||||
#else
|
|
||||||
Mode = "Release",
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LogLevel_Verbose_Enabled = Log.Logger.IsVerboseEnabled(),
|
LogLevel_Verbose_Enabled = Log.Logger.IsVerboseEnabled(),
|
||||||
LogLevel_Debug_Enabled = Log.Logger.IsDebugEnabled(),
|
LogLevel_Debug_Enabled = Log.Logger.IsDebugEnabled(),
|
||||||
LogLevel_Information_Enabled = Log.Logger.IsInformationEnabled(),
|
LogLevel_Information_Enabled = Log.Logger.IsInformationEnabled(),
|
||||||
|
|||||||
@ -124,7 +124,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBoxLib.ShowAdminAlert("Error attempting to save accounts", "Error saving accounts", ex);
|
MessageBoxLib.ShowAdminAlert(this, "Error attempting to save accounts", "Error saving accounts", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
|
|
||||||
if (template is null)
|
if (template is null)
|
||||||
{
|
{
|
||||||
MessageBoxLib.ShowAdminAlert($"Programming error. {nameof(EditTemplateDialog)} was not created correctly", "Edit template error", new NullReferenceException($"{nameof(template)} is null"));
|
MessageBoxLib.ShowAdminAlert(this, $"Programming error. {nameof(EditTemplateDialog)} was not created correctly", "Edit template error", new NullReferenceException($"{nameof(template)} is null"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBoxLib.ShowAdminAlert(
|
MessageBoxLib.ShowAdminAlert(
|
||||||
|
this,
|
||||||
"Error scanning library. You may still manually select books to remove from Libation's library.",
|
"Error scanning library. You may still manually select books to remove from Libation's library.",
|
||||||
"Error scanning library",
|
"Error scanning library",
|
||||||
ex);
|
ex);
|
||||||
|
|||||||
@ -40,7 +40,7 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBoxLib.ShowAdminAlert("Error attempting to export your library.", "Error exporting", ex);
|
MessageBoxLib.ShowAdminAlert(this, "Error attempting to export your library.", "Error exporting", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -126,6 +126,7 @@ namespace LibationWinForms
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBoxLib.ShowAdminAlert(
|
MessageBoxLib.ShowAdminAlert(
|
||||||
|
this,
|
||||||
"Error importing library. Please try again. If this still happens after 2 or 3 tries, stop and contact administrator",
|
"Error importing library. Please try again. If this still happens after 2 or 3 tries, stop and contact administrator",
|
||||||
"Error importing library",
|
"Error importing library",
|
||||||
ex);
|
ex);
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core.Logging;
|
using Dinah.Core.Logging;
|
||||||
|
using Dinah.Core.Threading;
|
||||||
using LibationWinForms.Dialogs;
|
using LibationWinForms.Dialogs;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
@ -14,12 +15,16 @@ namespace LibationWinForms
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Logs error. Displays a message box dialog with specified text and caption.
|
/// Logs error. Displays a message box dialog with specified text and caption.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="synchronizeInvoke">Form calling this method.</param>
|
||||||
/// <param name="text">The text to display in the message box.</param>
|
/// <param name="text">The text to display in the message box.</param>
|
||||||
/// <param name="caption">The text to display in the title bar of the message box.</param>
|
/// <param name="caption">The text to display in the title bar of the message box.</param>
|
||||||
/// <param name="exception">Exception to log</param>
|
/// <param name="exception">Exception to log.</param>
|
||||||
/// <returns>One of the System.Windows.Forms.DialogResult values.</returns>
|
public static void ShowAdminAlert(System.ComponentModel.ISynchronizeInvoke owner, string text, string caption, Exception exception)
|
||||||
public static DialogResult ShowAdminAlert(string text, string caption, Exception exception)
|
|
||||||
{
|
{
|
||||||
|
// for development and debugging, show me what broke!
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached)
|
||||||
|
throw exception;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Serilog.Log.Logger.Error(exception, "Alert admin error: {@DebugText}", new { text, caption });
|
Serilog.Log.Logger.Error(exception, "Alert admin error: {@DebugText}", new { text, caption });
|
||||||
@ -27,7 +32,19 @@ namespace LibationWinForms
|
|||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
using var form = new MessageBoxAlertAdminDialog(text, caption, exception);
|
using var form = new MessageBoxAlertAdminDialog(text, caption, exception);
|
||||||
return form.ShowDialog();
|
|
||||||
|
if (owner is not null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
owner.UIThreadSync(() => form.ShowDialog());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// synchronizeInvoke is null or previous attempt failed. final try
|
||||||
|
form.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void VerboseLoggingWarning_ShowIfTrue()
|
public static void VerboseLoggingWarning_ShowIfTrue()
|
||||||
|
|||||||
@ -49,7 +49,7 @@ namespace LibationWinForms
|
|||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
checkForUpdate();
|
checkForUpdate();
|
||||||
#endif
|
#endif
|
||||||
|
// logging is init'd here
|
||||||
AppScaffolding.LibationScaffolding.RunPostMigrationScaffolding(config);
|
AppScaffolding.LibationScaffolding.RunPostMigrationScaffolding(config);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -58,7 +58,7 @@ namespace LibationWinForms
|
|||||||
var body = "An unrecoverable error occurred. Since this error happened before logging could be initialized, this error can not be written to the log file.";
|
var body = "An unrecoverable error occurred. Since this error happened before logging could be initialized, this error can not be written to the log file.";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MessageBoxLib.ShowAdminAlert(body, title, ex);
|
MessageBoxLib.ShowAdminAlert(null, body, title, ex);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -67,6 +67,9 @@ namespace LibationWinForms
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// global exception handling (ShowAdminAlert) attempts to use logging. only call it after logging has been init'd
|
||||||
|
postLoggingGlobalExceptionHandling();
|
||||||
|
|
||||||
Application.Run(new Form1());
|
Application.Run(new Form1());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +173,7 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBoxLib.ShowAdminAlert("Error checking for update", "Error checking for update", ex);
|
MessageBoxLib.ShowAdminAlert(null, "Error checking for update", "Error checking for update", ex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,5 +185,16 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
Updater.Run(upgradeProperties.LatestRelease, upgradeProperties.ZipUrl);
|
Updater.Run(upgradeProperties.LatestRelease, upgradeProperties.ZipUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void postLoggingGlobalExceptionHandling()
|
||||||
|
{
|
||||||
|
// this line is all that's needed for strict handling
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += (_, e) => MessageBoxLib.ShowAdminAlert(null, "Libation has crashed due to an unhandled error.", "Application crash!", (Exception)e.ExceptionObject);
|
||||||
|
|
||||||
|
// these 2 lines makes it graceful. sync (eg in main form's ctor) and thread exceptions will still crash us, but event (sync, void async, Task async) will not
|
||||||
|
Application.ThreadException += (_, e) => MessageBoxLib.ShowAdminAlert(null, "Libation has encountered an unexpected error.", "Unexpected error", e.Exception);
|
||||||
|
// I never found a case where including made a difference. I think this enum is default and including it will override app user config file
|
||||||
|
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBoxLib.ShowAdminAlert("Error downloading update", "Error downloading update", ex);
|
MessageBoxLib.ShowAdminAlert(null, "Error downloading update", "Error downloading update", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user