mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-13 19:19:23 +08:00
Better exception report.
This commit is contained in:
parent
32e0074f26
commit
9d39b616f9
@ -10,21 +10,19 @@ namespace Wox.Core.Exception
|
|||||||
{
|
{
|
||||||
public class ExceptionFormatter
|
public class ExceptionFormatter
|
||||||
{
|
{
|
||||||
public static string FormatExcpetion(object exception)
|
public static string FormatExcpetion(System.Exception exception)
|
||||||
{
|
{
|
||||||
return CreateExceptionReport(exception);
|
return CreateExceptionReport(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateExceptionReport(object exceptionObject)
|
private static string CreateExceptionReport(System.Exception ex)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine();
|
||||||
sb.AppendLine("## Exception");
|
sb.AppendLine("## Exception");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
sb.AppendLine("```");
|
sb.AppendLine("```");
|
||||||
|
|
||||||
var ex = exceptionObject as System.Exception;
|
|
||||||
if (ex != null)
|
|
||||||
{
|
|
||||||
var exlist = new List<StringBuilder>();
|
var exlist = new List<StringBuilder>();
|
||||||
|
|
||||||
while (ex != null)
|
while (ex != null)
|
||||||
@ -59,14 +57,6 @@ namespace Wox.Core.Exception
|
|||||||
}
|
}
|
||||||
sb.AppendLine("```");
|
sb.AppendLine("```");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.AppendLine(exceptionObject.GetType().FullName);
|
|
||||||
sb.AppendLine(new StackTrace().ToString());
|
|
||||||
sb.AppendLine("```");
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine("## Environment");
|
sb.AppendLine("## Environment");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
@ -88,9 +78,9 @@ namespace Wox.Core.Exception
|
|||||||
}
|
}
|
||||||
|
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
sb.AppendLine("## Assemblies - " + System.AppDomain.CurrentDomain.FriendlyName);
|
sb.AppendLine("## Assemblies - " + AppDomain.CurrentDomain.FriendlyName);
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
foreach (var ass in System.AppDomain.CurrentDomain.GetAssemblies().OrderBy(o => o.GlobalAssemblyCache ? 100 : 0))
|
foreach (var ass in AppDomain.CurrentDomain.GetAssemblies().OrderBy(o => o.GlobalAssemblyCache ? 50 : 0))
|
||||||
{
|
{
|
||||||
sb.Append("* ");
|
sb.Append("* ");
|
||||||
sb.Append(ass.FullName);
|
sb.Append(ass.FullName);
|
||||||
@ -99,38 +89,6 @@ namespace Wox.Core.Exception
|
|||||||
sb.AppendLine(")");
|
sb.AppendLine(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
var process = System.Diagnostics.Process.GetCurrentProcess();
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("## Modules - " + process.ProcessName);
|
|
||||||
sb.AppendLine();
|
|
||||||
foreach (ProcessModule mod in process.Modules)
|
|
||||||
{
|
|
||||||
sb.Append("* ");
|
|
||||||
sb.Append(mod.FileName);
|
|
||||||
sb.Append(" (");
|
|
||||||
sb.Append(mod.FileVersionInfo.FileDescription);
|
|
||||||
sb.Append(", ");
|
|
||||||
sb.Append(mod.FileVersionInfo.FileVersion);
|
|
||||||
sb.Append(", ");
|
|
||||||
sb.Append(mod.FileVersionInfo.ProductName);
|
|
||||||
sb.Append(", ");
|
|
||||||
sb.Append(mod.FileVersionInfo.ProductVersion);
|
|
||||||
sb.Append(", ");
|
|
||||||
sb.Append(mod.FileVersionInfo.CompanyName);
|
|
||||||
sb.Append("), ");
|
|
||||||
sb.Append(string.Format("0x{0:X16}", mod.BaseAddress.ToInt64()));
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("## Threads - " + process.Threads.Count);
|
|
||||||
sb.AppendLine();
|
|
||||||
foreach (ProcessThread th in process.Threads)
|
|
||||||
{
|
|
||||||
sb.Append("* ");
|
|
||||||
sb.AppendLine(string.Format("{0}, {1} {2}, Started: {3}, StartAddress: 0x{4:X16}", th.Id, th.ThreadState, th.PriorityLevel, th.StartTime, th.StartAddress.ToInt64()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,5 +10,11 @@
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WoxException(string msg, System.Exception innerException)
|
||||||
|
: base(msg, innerException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
Wox.Core/Exception/WoxPluginException.cs
Normal file
18
Wox.Core/Exception/WoxPluginException.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Wox.Core.Exception
|
||||||
|
{
|
||||||
|
public class WoxPluginException : WoxException
|
||||||
|
{
|
||||||
|
public string PluginName { get; set; }
|
||||||
|
|
||||||
|
public WoxPluginException(string pluginName,System.Exception e)
|
||||||
|
: base(e.Message,e)
|
||||||
|
{
|
||||||
|
PluginName = pluginName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Wox.Core.Exception;
|
||||||
using Wox.Core.UserSettings;
|
using Wox.Core.UserSettings;
|
||||||
|
using Wox.Infrastructure.Logger;
|
||||||
using Wox.Plugin;
|
using Wox.Plugin;
|
||||||
//using Wox.Plugin.SystemPlugins;
|
//using Wox.Plugin.SystemPlugins;
|
||||||
|
|
||||||
@ -27,11 +29,18 @@ namespace Wox.Core.Plugin.QueryDispatcher
|
|||||||
{
|
{
|
||||||
PluginPair pair1 = pair;
|
PluginPair pair1 = pair;
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
List<Result> results = pair1.Plugin.Query(query);
|
List<Result> results = pair1.Plugin.Query(query);
|
||||||
results.ForEach(o => { o.AutoAjustScore = true; });
|
results.ForEach(o => { o.AutoAjustScore = true; });
|
||||||
|
|
||||||
PluginManager.API.PushResults(query, pair1.Metadata, results);
|
PluginManager.API.PushResults(query, pair1.Metadata, results);
|
||||||
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
throw new WoxPluginException(pair1.Metadata.Name,e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Wox.Core.Exception;
|
||||||
using Wox.Core.UserSettings;
|
using Wox.Core.UserSettings;
|
||||||
using Wox.Infrastructure.Logger;
|
using Wox.Infrastructure.Logger;
|
||||||
using Wox.Plugin;
|
using Wox.Plugin;
|
||||||
@ -30,15 +31,9 @@ namespace Wox.Core.Plugin.QueryDispatcher
|
|||||||
List<Result> results = userPlugin.Plugin.Query(query) ?? new List<Result>();
|
List<Result> results = userPlugin.Plugin.Query(query) ?? new List<Result>();
|
||||||
PluginManager.API.PushResults(query,userPlugin.Metadata,results);
|
PluginManager.API.PushResults(query,userPlugin.Metadata,results);
|
||||||
}
|
}
|
||||||
catch (System.Exception queryException)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
Log.Error(string.Format("Plugin {0} query failed: {1}", userPlugin.Metadata.Name,
|
throw new WoxPluginException(userPlugin.Metadata.Name, e);
|
||||||
queryException.Message));
|
|
||||||
#if (DEBUG)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
<Compile Include="Exception\WoxHttpException.cs" />
|
<Compile Include="Exception\WoxHttpException.cs" />
|
||||||
<Compile Include="Exception\WoxI18nException.cs" />
|
<Compile Include="Exception\WoxI18nException.cs" />
|
||||||
<Compile Include="Exception\WoxJsonRPCException.cs" />
|
<Compile Include="Exception\WoxJsonRPCException.cs" />
|
||||||
|
<Compile Include="Exception\WoxPluginException.cs" />
|
||||||
<Compile Include="UserSettings\HttpProxy.cs" />
|
<Compile Include="UserSettings\HttpProxy.cs" />
|
||||||
<Compile Include="i18n\AvailableLanguages.cs" />
|
<Compile Include="i18n\AvailableLanguages.cs" />
|
||||||
<Compile Include="i18n\IInternationalization.cs" />
|
<Compile Include="i18n\IInternationalization.cs" />
|
||||||
|
@ -18,6 +18,10 @@ namespace Wox.CrashReporter
|
|||||||
{
|
{
|
||||||
if (exception == null) return;
|
if (exception == null) return;
|
||||||
|
|
||||||
|
if (exception.InnerException != null)
|
||||||
|
{
|
||||||
|
exception = exception.InnerException;
|
||||||
|
}
|
||||||
ReportWindow reportWindow = new ReportWindow(exception);
|
ReportWindow reportWindow = new ReportWindow(exception);
|
||||||
reportWindow.Show();
|
reportWindow.Show();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
@ -47,6 +48,11 @@ namespace Wox.CrashReporter
|
|||||||
string sendingMsg = InternationalizationManager.Internationalization.GetTranslation("reportWindow_sending");
|
string sendingMsg = InternationalizationManager.Internationalization.GetTranslation("reportWindow_sending");
|
||||||
tbSendReport.Content = sendingMsg;
|
tbSendReport.Content = sendingMsg;
|
||||||
btnSend.IsEnabled = false;
|
btnSend.IsEnabled = false;
|
||||||
|
ThreadPool.QueueUserWorkItem(o => SendReport());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendReport()
|
||||||
|
{
|
||||||
string error = string.Format("{{\"data\":{0}}}", ExceptionFormatter.FormatExcpetion(exception));
|
string error = string.Format("{{\"data\":{0}}}", ExceptionFormatter.FormatExcpetion(exception));
|
||||||
string response = HttpRequest.Post(APIServer.ErrorReportURL, error, HttpProxy.Instance);
|
string response = HttpRequest.Post(APIServer.ErrorReportURL, error, HttpProxy.Instance);
|
||||||
if (response.ToLower() == "ok")
|
if (response.ToLower() == "ok")
|
||||||
@ -57,7 +63,7 @@ namespace Wox.CrashReporter
|
|||||||
{
|
{
|
||||||
MessageBox.Show(InternationalizationManager.Internationalization.GetTranslation("reportWindow_report_failed"));
|
MessageBox.Show(InternationalizationManager.Internationalization.GetTranslation("reportWindow_report_failed"));
|
||||||
}
|
}
|
||||||
Close();
|
Dispatcher.Invoke(new Action(Close));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnCancel_Click(object sender, RoutedEventArgs e)
|
private void btnCancel_Click(object sender, RoutedEventArgs e)
|
||||||
|
@ -26,7 +26,12 @@
|
|||||||
</root>
|
</root>
|
||||||
</log4net>
|
</log4net>
|
||||||
<runtime>
|
<runtime>
|
||||||
<!--http://stackoverflow.com/questions/186854/how-to-prevent-an-exception-in-a-background-thread-from-terminating-an-applicati-->
|
<!--http://stackoverflow.com/questions/186854/how-to-prevent-an-exception-in-a-background-thread-from-terminating-an-application-->
|
||||||
|
<!--prevent non-ui exception crash wox-->
|
||||||
<legacyUnhandledExceptionPolicy enabled="1"/>
|
<legacyUnhandledExceptionPolicy enabled="1"/>
|
||||||
</runtime>
|
</runtime>
|
||||||
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
|
<startup>
|
||||||
|
<supportedRuntime version="v2.0.50727"/>
|
||||||
|
<supportedRuntime version="v4.0"/>
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
|
@ -33,7 +33,6 @@ namespace Wox
|
|||||||
base.OnStartup(e);
|
base.OnStartup(e);
|
||||||
DispatcherUnhandledException += ErrorReporting.DispatcherUnhandledException;
|
DispatcherUnhandledException += ErrorReporting.DispatcherUnhandledException;
|
||||||
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle;
|
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle;
|
||||||
System.Windows.Forms.Application.ThreadException += ErrorReporting.ThreadException;
|
|
||||||
|
|
||||||
Window = new MainWindow();
|
Window = new MainWindow();
|
||||||
CommandArgsFactory.Execute(e.Args.ToList());
|
CommandArgsFactory.Execute(e.Args.ToList());
|
||||||
|
@ -5,31 +5,38 @@ using System.Windows.Forms;
|
|||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using Wox.Core.Exception;
|
using Wox.Core.Exception;
|
||||||
using Wox.Infrastructure.Logger;
|
using Wox.Infrastructure.Logger;
|
||||||
|
using MessageBox = System.Windows.MessageBox;
|
||||||
|
|
||||||
namespace Wox.Helper
|
namespace Wox.Helper
|
||||||
{
|
{
|
||||||
public static class ErrorReporting
|
public static class ErrorReporting
|
||||||
{
|
{
|
||||||
private static void Report(Exception e)
|
public static void Report(Exception e)
|
||||||
{
|
{
|
||||||
//if (Debugger.IsAttached) return;
|
if (Debugger.IsAttached) return;
|
||||||
Log.Error(ExceptionFormatter.FormatExcpetion(e));
|
Log.Error(ExceptionFormatter.FormatExcpetion(e));
|
||||||
new CrashReporter.CrashReporter(e).Show();
|
new CrashReporter.CrashReporter(e).Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UnhandledExceptionHandle(object sender, UnhandledExceptionEventArgs e)
|
public static void UnhandledExceptionHandle(object sender, UnhandledExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
//handle non-ui thread exceptions
|
||||||
|
App.Window.Dispatcher.Invoke(new Action(() =>
|
||||||
{
|
{
|
||||||
Report((Exception)e.ExceptionObject);
|
Report((Exception)e.ExceptionObject);
|
||||||
|
if (!(e.ExceptionObject is WoxException))
|
||||||
|
{
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
public static void DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
|
//handle ui thread exceptions
|
||||||
Report(e.Exception);
|
Report(e.Exception);
|
||||||
}
|
//prevent crash
|
||||||
|
e.Handled = true;
|
||||||
public static void ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
|
|
||||||
{
|
|
||||||
Report(e.Exception);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -353,28 +353,38 @@ namespace Wox
|
|||||||
Dispatcher.DelayInvoke("ClearResults", i =>
|
Dispatcher.DelayInvoke("ClearResults", i =>
|
||||||
{
|
{
|
||||||
// first try to use clear method inside pnlResult, which is more closer to the add new results
|
// first try to use clear method inside pnlResult, which is more closer to the add new results
|
||||||
// and this will not bring splash issues.After waiting 30ms, if there still no results added, we
|
// and this will not bring splash issues.After waiting 100ms, if there still no results added, we
|
||||||
// must clear the result. otherwise, it will be confused why the query changed, but the results
|
// must clear the result. otherwise, it will be confused why the query changed, but the results
|
||||||
// didn't.
|
// didn't.
|
||||||
if (pnlResult.Dirty) pnlResult.Clear();
|
if (pnlResult.Dirty) pnlResult.Clear();
|
||||||
}, TimeSpan.FromMilliseconds(100), null);
|
}, TimeSpan.FromMilliseconds(100), null);
|
||||||
queryHasReturn = false;
|
queryHasReturn = false;
|
||||||
var q = new Query(lastQuery);
|
var q = new Query(lastQuery);
|
||||||
PluginManager.Query(q);
|
Query(q);
|
||||||
BackToResultMode();
|
BackToResultMode();
|
||||||
if (PluginManager.IsUserPluginQuery(q))
|
|
||||||
{
|
|
||||||
Dispatcher.DelayInvoke("ShowProgressbar", originQuery =>
|
Dispatcher.DelayInvoke("ShowProgressbar", originQuery =>
|
||||||
{
|
{
|
||||||
if (!queryHasReturn && originQuery == lastQuery)
|
if (!queryHasReturn && originQuery == lastQuery)
|
||||||
{
|
{
|
||||||
StartProgress();
|
StartProgress();
|
||||||
}
|
}
|
||||||
}, TimeSpan.FromSeconds(0), lastQuery);
|
}, TimeSpan.FromMilliseconds(150), lastQuery);
|
||||||
}
|
|
||||||
}, TimeSpan.FromMilliseconds(ShouldNotDelayQuery ? 0 : 200));
|
}, TimeSpan.FromMilliseconds(ShouldNotDelayQuery ? 0 : 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Query(Query q)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PluginManager.Query(q);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
StopProgress();
|
||||||
|
ErrorReporting.Report(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void BackToResultMode()
|
private void BackToResultMode()
|
||||||
{
|
{
|
||||||
pnlResult.Visibility = Visibility.Visible;
|
pnlResult.Visibility = Visibility.Visible;
|
||||||
|
Loading…
Reference in New Issue
Block a user