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