diff --git a/Source/LibationWinForms/MessageBoxLib.cs b/Source/LibationWinForms/MessageBoxLib.cs index 62a7f9f8..ad4e0ad7 100644 --- a/Source/LibationWinForms/MessageBoxLib.cs +++ b/Source/LibationWinForms/MessageBoxLib.cs @@ -12,17 +12,34 @@ namespace LibationWinForms { public static class MessageBoxLib { - /// - /// Logs error. Displays a message box dialog with specified text and caption. - /// - /// Form calling this method. - /// The text to display in the message box. - /// The text to display in the title bar of the message box. - /// Exception to log. - public static void ShowAdminAlert(System.ComponentModel.ISynchronizeInvoke owner, string text, string caption, Exception exception) + private static int nreCount = 0; + private const int NRE_LIMIT = 5; + + /// + /// Logs error. Displays a message box dialog with specified text and caption. + /// + /// Form calling this method. + /// The text to display in the message box. + /// The text to display in the title bar of the message box. + /// Exception to log. + public static void ShowAdminAlert(System.ComponentModel.ISynchronizeInvoke owner, string text, string caption, Exception exception) { - // for development and debugging, show me what broke! - if (System.Diagnostics.Debugger.IsAttached) + // HACK: limited NRE swallowing -- this. is. AWFUL + // I can't figure out how to circumvent the DataGridView internal NRE when: + // * book has tag: asdf + // * filter is `[asdf]` + // * tag asdf is removed from book + // * DataGridView throws NRE + if (exception is NullReferenceException nre && nreCount < NRE_LIMIT) + { + nreCount++; + Serilog.Log.Logger.Error(nre, "Alert admin error. Swallow NRE: {@DebugText}", new { text, caption, nreCount }); + return; + } + + + // for development and debugging, show me what broke! + if (System.Diagnostics.Debugger.IsAttached) throw exception; try