diff --git a/Wox.Core/Exception/ExceptionFormatter.cs b/Wox.Core/Exception/ExceptionFormatter.cs index ee3095b3e2..7db7b07a03 100644 --- a/Wox.Core/Exception/ExceptionFormatter.cs +++ b/Wox.Core/Exception/ExceptionFormatter.cs @@ -10,21 +10,19 @@ namespace Wox.Core.Exception { public class ExceptionFormatter { - public static string FormatExcpetion(object exception) + public static string FormatExcpetion(System.Exception exception) { return CreateExceptionReport(exception); } - private static string CreateExceptionReport(object exceptionObject) + private static string CreateExceptionReport(System.Exception ex) { var sb = new StringBuilder(); + sb.AppendLine(); sb.AppendLine("## Exception"); sb.AppendLine(); sb.AppendLine("```"); - var ex = exceptionObject as System.Exception; - if (ex != null) - { var exlist = new List(); while (ex != null) @@ -59,14 +57,6 @@ namespace Wox.Core.Exception } sb.AppendLine("```"); sb.AppendLine(); - } - else - { - sb.AppendLine(exceptionObject.GetType().FullName); - sb.AppendLine(new StackTrace().ToString()); - sb.AppendLine("```"); - sb.AppendLine(); - } sb.AppendLine("## Environment"); sb.AppendLine(); @@ -88,9 +78,9 @@ namespace Wox.Core.Exception } sb.AppendLine(); - sb.AppendLine("## Assemblies - " + System.AppDomain.CurrentDomain.FriendlyName); + sb.AppendLine("## Assemblies - " + AppDomain.CurrentDomain.FriendlyName); 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(ass.FullName); @@ -99,38 +89,6 @@ namespace Wox.Core.Exception 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(); } diff --git a/Wox.Core/Exception/WoxException.cs b/Wox.Core/Exception/WoxException.cs index a5df7a3d34..2840e34aaa 100644 --- a/Wox.Core/Exception/WoxException.cs +++ b/Wox.Core/Exception/WoxException.cs @@ -10,5 +10,11 @@ { } + + public WoxException(string msg, System.Exception innerException) + : base(msg, innerException) + { + + } } } diff --git a/Wox.Core/Exception/WoxPluginException.cs b/Wox.Core/Exception/WoxPluginException.cs new file mode 100644 index 0000000000..1134460321 --- /dev/null +++ b/Wox.Core/Exception/WoxPluginException.cs @@ -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; + } + } +} diff --git a/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs index 155e6a006e..c69e591328 100644 --- a/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs +++ b/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using Wox.Core.Exception; using Wox.Core.UserSettings; +using Wox.Infrastructure.Logger; using Wox.Plugin; //using Wox.Plugin.SystemPlugins; @@ -28,10 +30,17 @@ namespace Wox.Core.Plugin.QueryDispatcher PluginPair pair1 = pair; ThreadPool.QueueUserWorkItem(state => { - List results = pair1.Plugin.Query(query); - results.ForEach(o => { o.AutoAjustScore = true; }); + try + { + List results = pair1.Plugin.Query(query); + 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); + } }); } } diff --git a/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs index 1f742366ca..9b42179633 100644 --- a/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs +++ b/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using Wox.Core.Exception; using Wox.Core.UserSettings; using Wox.Infrastructure.Logger; using Wox.Plugin; @@ -30,15 +31,9 @@ namespace Wox.Core.Plugin.QueryDispatcher List results = userPlugin.Plugin.Query(query) ?? new List(); 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, - queryException.Message)); -#if (DEBUG) - { - throw; - } -#endif + throw new WoxPluginException(userPlugin.Metadata.Name, e); } }); } diff --git a/Wox.Core/Wox.Core.csproj b/Wox.Core/Wox.Core.csproj index de8c22e29c..05aff0cd08 100644 --- a/Wox.Core/Wox.Core.csproj +++ b/Wox.Core/Wox.Core.csproj @@ -64,6 +64,7 @@ + diff --git a/Wox.CrashReporter/CrashReporter.cs b/Wox.CrashReporter/CrashReporter.cs index 3ca1e9b548..41f4fc9b97 100644 --- a/Wox.CrashReporter/CrashReporter.cs +++ b/Wox.CrashReporter/CrashReporter.cs @@ -18,6 +18,10 @@ namespace Wox.CrashReporter { if (exception == null) return; + if (exception.InnerException != null) + { + exception = exception.InnerException; + } ReportWindow reportWindow = new ReportWindow(exception); reportWindow.Show(); } diff --git a/Wox.CrashReporter/ReportWindow.xaml.cs b/Wox.CrashReporter/ReportWindow.xaml.cs index 2d09206ebb..55ec0555b7 100644 --- a/Wox.CrashReporter/ReportWindow.xaml.cs +++ b/Wox.CrashReporter/ReportWindow.xaml.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Data; @@ -47,6 +48,11 @@ namespace Wox.CrashReporter string sendingMsg = InternationalizationManager.Internationalization.GetTranslation("reportWindow_sending"); tbSendReport.Content = sendingMsg; btnSend.IsEnabled = false; + ThreadPool.QueueUserWorkItem(o => SendReport()); + } + + private void SendReport() + { string error = string.Format("{{\"data\":{0}}}", ExceptionFormatter.FormatExcpetion(exception)); string response = HttpRequest.Post(APIServer.ErrorReportURL, error, HttpProxy.Instance); if (response.ToLower() == "ok") @@ -57,7 +63,7 @@ namespace Wox.CrashReporter { MessageBox.Show(InternationalizationManager.Internationalization.GetTranslation("reportWindow_report_failed")); } - Close(); + Dispatcher.Invoke(new Action(Close)); } private void btnCancel_Click(object sender, RoutedEventArgs e) diff --git a/Wox/App.config b/Wox/App.config index bef03f123f..2d597ab062 100644 --- a/Wox/App.config +++ b/Wox/App.config @@ -26,7 +26,12 @@ - + + - + + + + + diff --git a/Wox/App.xaml.cs b/Wox/App.xaml.cs index 602fd19715..d1b7f5f69b 100644 --- a/Wox/App.xaml.cs +++ b/Wox/App.xaml.cs @@ -33,7 +33,6 @@ namespace Wox base.OnStartup(e); DispatcherUnhandledException += ErrorReporting.DispatcherUnhandledException; AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle; - System.Windows.Forms.Application.ThreadException += ErrorReporting.ThreadException; Window = new MainWindow(); CommandArgsFactory.Execute(e.Args.ToList()); diff --git a/Wox/Helper/ErrorReporting.cs b/Wox/Helper/ErrorReporting.cs index af7b47b9ae..cff796318f 100644 --- a/Wox/Helper/ErrorReporting.cs +++ b/Wox/Helper/ErrorReporting.cs @@ -5,31 +5,38 @@ using System.Windows.Forms; using System.Windows.Threading; using Wox.Core.Exception; using Wox.Infrastructure.Logger; +using MessageBox = System.Windows.MessageBox; namespace Wox.Helper { 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)); new CrashReporter.CrashReporter(e).Show(); } public static void UnhandledExceptionHandle(object sender, UnhandledExceptionEventArgs e) { - Report((Exception)e.ExceptionObject); + //handle non-ui thread exceptions + App.Window.Dispatcher.Invoke(new Action(() => + { + Report((Exception)e.ExceptionObject); + if (!(e.ExceptionObject is WoxException)) + { + Environment.Exit(0); + } + })); } public static void DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { + //handle ui thread exceptions Report(e.Exception); - } - - public static void ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) - { - Report(e.Exception); + //prevent crash + e.Handled = true; } } } diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 54061baf14..a61d37ff83 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -353,28 +353,38 @@ namespace Wox Dispatcher.DelayInvoke("ClearResults", i => { // 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 // didn't. if (pnlResult.Dirty) pnlResult.Clear(); }, TimeSpan.FromMilliseconds(100), null); queryHasReturn = false; var q = new Query(lastQuery); - PluginManager.Query(q); + Query(q); BackToResultMode(); - if (PluginManager.IsUserPluginQuery(q)) + Dispatcher.DelayInvoke("ShowProgressbar", originQuery => { - Dispatcher.DelayInvoke("ShowProgressbar", originQuery => + if (!queryHasReturn && originQuery == lastQuery) { - if (!queryHasReturn && originQuery == lastQuery) - { - StartProgress(); - } - }, TimeSpan.FromSeconds(0), lastQuery); - } + StartProgress(); + } + }, TimeSpan.FromMilliseconds(150), lastQuery); }, TimeSpan.FromMilliseconds(ShouldNotDelayQuery ? 0 : 200)); } + private void Query(Query q) + { + try + { + PluginManager.Query(q); + } + catch (Exception e) + { + StopProgress(); + ErrorReporting.Report(e); + } + } + private void BackToResultMode() { pnlResult.Visibility = Visibility.Visible;