Прежде всего, я бы поймал эти необработанные исключения, например:
public MyCustomControl()
{
Dispatcher.UnhandledException += Dispatcher_UnhandledException;
}
void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
switch (e.Exception)
{
case AnimationException aniEx:
Log(aniEx.GetDetails());
break;
// ...
// default: ...
}
}
, а во-вторых, я бы добавил расширение GetDetails для исключений, чтобы получить из него все детали:
public static class Extensions
{
/// <summary>
/// Returns all Details of an exception
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
public static string GetDetails(this Exception exception)
{
string GetInnerExceptionDetails(Exception e)
{
var s = new StringBuilder(e.GetType().FullName);
if (e.GetType().GetProperties()
.Select(prop => new { prop.Name, Value = prop.GetValue(e, null) })
.Select(x => $"{x.Name}: {x.Value ?? string.Empty}").ToList() is List<string> props && props.Any())
{
s.AppendLine(string.Join(Environment.NewLine, props));
s.AppendLine();
}
if (e.InnerException != null)
s.AppendLine(GetInnerExceptionDetails(e.InnerException));
return s.ToString();
}
return GetInnerExceptionDetails(exception);
}
}