|
@@ -318,11 +318,50 @@ namespace PRSDesktop
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ private class UnhandledException
|
|
|
+ {
|
|
|
+ private string _message;
|
|
|
+ public string Message
|
|
|
+ {
|
|
|
+ get => _message;
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _message = value;
|
|
|
+ Hash = GenerateExceptionHash(value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public DateTime OriginalTime { get; set; }
|
|
|
+
|
|
|
+ public DateTime LastTime { get; set; }
|
|
|
+
|
|
|
+ public DateTime LastPrinted { get; set; }
|
|
|
+
|
|
|
+ public int Occurences { get; set; }
|
|
|
+
|
|
|
+ public int Hash { get; private set; }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static TimeSpan RepeatedExceptionThreshold = TimeSpan.FromSeconds(10);
|
|
|
+
|
|
|
+ private static Queue<UnhandledException> PreviousUnhandledExceptions { get; set; } = new Queue<UnhandledException>();
|
|
|
+
|
|
|
+ private static int GenerateExceptionHash(string message)
|
|
|
+ {
|
|
|
+ return message.GetHashCode();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void ClearUnhandledExceptions()
|
|
|
+ {
|
|
|
+ while (PreviousUnhandledExceptions.TryPeek(out var e) && DateTime.Now - e.LastTime > RepeatedExceptionThreshold)
|
|
|
+ {
|
|
|
+ PreviousUnhandledExceptions.Dequeue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private void LogUnhandledException(Exception exception, string source)
|
|
|
{
|
|
|
- // Hacky Hack Hack FastReport.WPF throwing errors here
|
|
|
- if (exception.Message.Contains("Must create DependencySource on same Thread as the DependencyObject."))
|
|
|
- return;
|
|
|
+ ClearUnhandledExceptions();
|
|
|
|
|
|
var messages = new List<string>();
|
|
|
var e2 = exception;
|
|
@@ -332,7 +371,40 @@ namespace PRSDesktop
|
|
|
e2 = e2.InnerException;
|
|
|
}
|
|
|
|
|
|
- MainLogger.Send(LogType.Error, "", string.Join("\n", messages));
|
|
|
+ var unhandled = new UnhandledException
|
|
|
+ {
|
|
|
+ Message = string.Join("\n", messages),
|
|
|
+ OriginalTime = DateTime.Now,
|
|
|
+ Occurences = 1
|
|
|
+ };
|
|
|
+ unhandled.LastTime = unhandled.OriginalTime;
|
|
|
+ unhandled.LastPrinted = unhandled.OriginalTime;
|
|
|
+
|
|
|
+ UnhandledException? found = null;
|
|
|
+ foreach(var e in PreviousUnhandledExceptions)
|
|
|
+ {
|
|
|
+ if(e.Hash == unhandled.Hash)
|
|
|
+ {
|
|
|
+ e.LastTime = unhandled.LastTime;
|
|
|
+ e.Occurences++;
|
|
|
+ found = e;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (found is null)
|
|
|
+ {
|
|
|
+ PreviousUnhandledExceptions.Enqueue(unhandled);
|
|
|
+ MainLogger.Send(LogType.Error, "", string.Join("\n", messages));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if((DateTime.Now - found.LastPrinted).TotalSeconds >= 1)
|
|
|
+ {
|
|
|
+ MainLogger.Send(LogType.Error, "", $"Recurrent Error occurred {found.Occurences} times; See {found.OriginalTime}");
|
|
|
+ found.LastPrinted = DateTime.Now;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
// if (exception.Message.StartsWith("Dispatcher processing has been suspended"))
|
|
|
// try
|