示例#1
0
        private void ShowNotifyDialog(string severity, string messageText, Exception exception,
                                      string reportButtonLabel, string secondaryButtonLabel)
        {
            // Before we do anything that might be "risky", put the problem in the log.
            ProblemReportApi.LogProblem(exception, messageText, severity);

            // ENHANCE: Allow the caller to pass in the control, which would be at the front of this.
            //System.Windows.Forms.Control control = Form.ActiveForm ?? FatalExceptionHandler.ControlOnUIThread;
            var control        = GetControlToUse();
            var isSyncRequired = false;

            SafeInvoke.InvokeIfPossible("Show Error Reporter", control, isSyncRequired, () =>
            {
                // Uses a browser dialog to show the problem report
                try
                {
                    StartupScreenManager.CloseSplashScreen();                     // if it's still up, it'll be on top of the dialog

                    var message = GetMessage(messageText, exception);

                    if (!Api.BloomServer.ServerIsListening)
                    {
                        // There's no hope of using the HtmlErrorReporter dialog if our server is not yet running.
                        // We'll likely get errors, maybe Javascript alerts, that won't lead to a clean fallback to
                        // the exception handler below. Besides, failure of HtmlErrorReporter in these circumstances
                        // is expected; we just want to cleanly report the original problem, not to report a
                        // failure of error handling.

                        // Note: HtmlErrorReporter supports up to 3 buttons (OK, Report, and [Secondary action]), but the fallback reporter only supports a max of two.
                        // Well, just going to have to drop the secondary action.

                        ShowFallbackProblemDialog(severity, exception, messageText, null, false);
                        return;
                    }

                    object props = new { level = ProblemLevel.kNotify, reportLabel = reportButtonLabel, secondaryLabel = secondaryButtonLabel, message = message };

                    // Precondition: we must be on the UI thread for Gecko to work.
                    using (var dlg = BrowserDialogFactory.CreateReactDialog("problemReportBundle", props))
                    {
                        dlg.FormBorderStyle = FormBorderStyle.FixedToolWindow; // Allows the window to be dragged around
                        dlg.ControlBox      = true;                            // Add controls like the X button back to the top bar
                        dlg.Text            = "";                              // Remove the title from the WinForms top bar

                        dlg.Width = 620;

                        // 360px was experimentally determined as what was needed for the longest known text for NotifyUserOfProblem
                        // (which is "Before saving, Bloom did an integrity check of your book [...]" from BookStorage.cs)
                        // You can make this height taller if need be.
                        // A scrollbar will appear if the height is not tall enough for the text
                        dlg.Height = 360;

                        // ShowDialog will cause this thread to be blocked (because it spins up a modal) until the dialog is closed.
                        BloomServer.RegisterThreadBlocking();

                        try
                        {
                            dlg.ShowDialog();

                            // Take action if the user clicked a button other than Close
                            if (dlg.CloseSource == "closedByAlternateButton" && OnSecondaryActionPressed != null)
                            {
                                OnSecondaryActionPressed(exception, message);
                            }
                            else if (dlg.CloseSource == "closedByReportButton")
                            {
                                if (OnReportButtonPressed != null)
                                {
                                    OnReportButtonPressed(exception, message);
                                }
                                else
                                {
                                    DefaultOnReportPressed(exception, message);
                                }
                            }

                            // Note: With the way LibPalaso's ErrorReport is designed,
                            // its intention is that after OnShowDetails is invoked and closed, you will not come back to the Notify Dialog
                            // This code has been implemented to follow that model
                            //
                            // But now that we have more options, it might be nice to come back to this dialog.
                            // If so, you'd need to add/update some code in this section.
                        }
                        finally
                        {
                            ResetToDefaults();
                            BloomServer.RegisterThreadUnblocked();
                        }
                    }
                }
                catch (Exception errorReporterException)
                {
                    Logger.WriteError("*** HtmlErrorReporter threw an exception trying to display", errorReporterException);
                    // At this point our problem reporter has failed for some reason, so we want the old WinForms handler
                    // to report both the original error for which we tried to open our dialog and this new one where
                    // the dialog itself failed.
                    // In order to do that, we create a new exception with the original exception (if there was one) as the
                    // inner exception. We include the message of the exception we just caught. Then we call the
                    // old WinForms fatal exception report directly.
                    // In any case, both of the errors will be logged by now.
                    var message = "Bloom's error reporting failed: " + errorReporterException.Message;

                    // Fallback to Winforms in case of trouble getting the browser to work
                    var fallbackReporter = new WinFormsErrorReporter();
                    // Food for thought: is it really fatal of the Notify Dialog had an exception? Maybe NonFatal makes more sense
                    fallbackReporter.ReportFatalException(new ApplicationException(message, exception ?? errorReporterException));
                }
            });
        }