Merge branch 'wip/713006-better-error-reporting'. Fixes Bug 713006.
This commit is contained in:
commit
d1d8d6411e
23 changed files with 1492 additions and 378 deletions
6
INSTALL
6
INSTALL
|
|
@ -46,6 +46,7 @@
|
|||
* webkit2gtk-4.0
|
||||
* gcr-3
|
||||
* enchant
|
||||
* libunwind
|
||||
* messaging-menu (optional; enables support for Ubuntu Unity
|
||||
messaging menu)
|
||||
* unity (optional; enables support for Ubuntu Unity launcher)
|
||||
|
|
@ -67,7 +68,7 @@
|
|||
desktop-file-utils gnome-doc-utils libcanberra-devel libgee-devel \
|
||||
glib2-devel gmime-devel gtk3-devel libnotify-devel sqlite-devel \
|
||||
webkitgtk4-devel libsecret-devel libxml2-devel vala-tools \
|
||||
gcr-devel enchant-devel
|
||||
gcr-devel enchant-devel libunwind-devel
|
||||
|
||||
|
||||
* Installing dependencies on Ubuntu/Debian
|
||||
|
|
@ -86,7 +87,8 @@
|
|||
cmake desktop-file-utils gnome-doc-utils libcanberra-dev \
|
||||
libgee-0.8-dev libglib2.0-dev libgmime-2.6-dev libgtk-3-dev \
|
||||
libsecret-1-dev libxml2-dev libnotify-dev libsqlite3-dev \
|
||||
libwebkit2gtk-4.0-dev libgcr-3-dev libenchant-dev
|
||||
libwebkit2gtk-4.0-dev libgcr-3-dev libenchant-dev \
|
||||
libunwind-dev
|
||||
|
||||
And for Ubuntu Unity integration:
|
||||
|
||||
|
|
|
|||
91
bindings/vapi/libunwind.vapi
Normal file
91
bindings/vapi/libunwind.vapi
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Based on version from Sentry-GLib: https://github.com/arteymix/sentry-glib
|
||||
* Courtesy of Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
|
||||
*
|
||||
* Copyright (C) 1996 X Consortium
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the X Consortium
|
||||
* shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written
|
||||
* authorization from the X Consortium.
|
||||
*
|
||||
* X Window System is a trademark of X Consortium, Inc.
|
||||
*/
|
||||
|
||||
[CCode (cprefix = "UNW_", lower_case_cprefix = "unw_", cheader_filename = "libunwind.h")]
|
||||
namespace Unwind
|
||||
{
|
||||
|
||||
[CCode (cname = "unw_context_t")]
|
||||
public struct Context
|
||||
{
|
||||
[CCode (cname = "unw_getcontext")]
|
||||
public Context ();
|
||||
}
|
||||
|
||||
[CCode (cname = "unw_proc_info_t")]
|
||||
public struct ProcInfo
|
||||
{
|
||||
void* start_ip;
|
||||
void* end_ip;
|
||||
void* lsda;
|
||||
void* handler;
|
||||
void* gp;
|
||||
long flags;
|
||||
int format;
|
||||
}
|
||||
|
||||
[CCode (cname = "unw_frame_regnum_t")]
|
||||
public enum Reg
|
||||
{
|
||||
IP,
|
||||
SP,
|
||||
EH
|
||||
}
|
||||
|
||||
[CCode (cname = "unw_cursor_t", cprefix = "unw_")]
|
||||
public struct Cursor
|
||||
{
|
||||
public Cursor.local (Context ctx);
|
||||
public int get_proc_info (out ProcInfo pip);
|
||||
public int get_proc_name (uint8[] bufp, out long offp = null);
|
||||
public int get_reg (Reg reg, out void* valp);
|
||||
public int step ();
|
||||
}
|
||||
|
||||
[CCode (cname = "unw_error_t", cprefix = "UNW_E", has_type_id = false)]
|
||||
public enum Error
|
||||
{
|
||||
SUCCESS,
|
||||
UNSPEC,
|
||||
NOMEM,
|
||||
BADREG,
|
||||
READONLYREG,
|
||||
STOPUNWIND,
|
||||
INVALIDIP,
|
||||
BADFRAME,
|
||||
INVAL,
|
||||
BADVERSION,
|
||||
NOINFO
|
||||
}
|
||||
|
||||
}
|
||||
2
debian/control
vendored
2
debian/control
vendored
|
|
@ -23,6 +23,7 @@ Build-Depends: debhelper (>= 8),
|
|||
gnome-doc-utils,
|
||||
libgcr-3-dev (>= 3.10.1),
|
||||
libenchant-dev (>= 1.6.0)
|
||||
libunwind8-dev (>= 1.1)
|
||||
Standards-Version: 3.8.3
|
||||
Homepage: https://wiki.gnome.org/Apps/Geary
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends},
|
|||
libgcr-base-3-1 (>= 3.10.1),
|
||||
libgcr-ui-3-1 (>= 3.10.1),
|
||||
libenchant1c2a (>= 1.6.0)
|
||||
libunwind8 (>= 1.1)
|
||||
Description: Email application
|
||||
Geary is an email application built around conversations, for the
|
||||
GNOME 3 desktop. It allows you to read, find and send email with a
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ src/client/components/folder-popover.vala
|
|||
src/client/components/icon-factory.vala
|
||||
src/client/components/main-toolbar.vala
|
||||
src/client/components/main-window.vala
|
||||
src/client/components/main-window-info-bar.vala
|
||||
src/client/components/monitored-progress-bar.vala
|
||||
src/client/components/monitored-spinner.vala
|
||||
src/client/components/search-bar.vala
|
||||
|
|
@ -128,6 +129,7 @@ src/engine/api/geary-folder.vala
|
|||
src/engine/api/geary-logging.vala
|
||||
src/engine/api/geary-named-flag.vala
|
||||
src/engine/api/geary-named-flags.vala
|
||||
src/engine/api/geary-problem-report.vala
|
||||
src/engine/api/geary-progress-monitor.vala
|
||||
src/engine/api/geary-revokable.vala
|
||||
src/engine/api/geary-search-folder.vala
|
||||
|
|
@ -414,6 +416,7 @@ ui/login.glade
|
|||
ui/main-toolbar.ui
|
||||
ui/main-toolbar-menus.ui
|
||||
ui/main-window.ui
|
||||
ui/main-window-info-bar.ui
|
||||
ui/password-dialog.glade
|
||||
ui/preferences-dialog.ui
|
||||
ui/remove_confirm.glade
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ engine/api/geary-folder-supports-remove.vala
|
|||
engine/api/geary-logging.vala
|
||||
engine/api/geary-named-flag.vala
|
||||
engine/api/geary-named-flags.vala
|
||||
engine/api/geary-problem-report.vala
|
||||
engine/api/geary-progress-monitor.vala
|
||||
engine/api/geary-revokable.vala
|
||||
engine/api/geary-search-folder.vala
|
||||
|
|
@ -345,6 +346,7 @@ client/components/folder-popover.vala
|
|||
client/components/icon-factory.vala
|
||||
client/components/main-toolbar.vala
|
||||
client/components/main-window.vala
|
||||
client/components/main-window-info-bar.vala
|
||||
client/components/monitored-progress-bar.vala
|
||||
client/components/monitored-spinner.vala
|
||||
client/components/search-bar.vala
|
||||
|
|
@ -513,6 +515,7 @@ pkg_check_modules(DEPS REQUIRED
|
|||
webkit2gtk-web-extension-4.0>=${TARGET_WEBKIT}
|
||||
javascriptcoregtk-4.0>=${TARGET_WEBKIT}
|
||||
enchant>=1.6
|
||||
libunwind-generic>=1.1
|
||||
${EXTRA_CLIENT_PKG_CONFIG}
|
||||
)
|
||||
|
||||
|
|
@ -530,6 +533,7 @@ set(ENGINE_PACKAGES
|
|||
gio-2.0
|
||||
glib-2.0
|
||||
gmime-2.6
|
||||
libunwind
|
||||
javascriptcore-4.0
|
||||
libxml-2.0
|
||||
posix
|
||||
|
|
|
|||
|
|
@ -869,44 +869,72 @@ public class GearyController : Geary.BaseObject {
|
|||
debug("Error updating stored passwords: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_report_problem(Geary.Account account, Geary.Account.Problem problem, Error? err) {
|
||||
debug("Reported problem: %s Error: %s", problem.to_string(), err != null ? err.message : "(N/A)");
|
||||
|
||||
switch (problem) {
|
||||
case Geary.Account.Problem.DATABASE_FAILURE:
|
||||
case Geary.Account.Problem.HOST_UNREACHABLE:
|
||||
case Geary.Account.Problem.NETWORK_UNAVAILABLE:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case Geary.Account.Problem.RECV_EMAIL_LOGIN_FAILED:
|
||||
case Geary.Account.Problem.SEND_EMAIL_LOGIN_FAILED:
|
||||
// At this point, we've prompted them for the password and
|
||||
// they've hit cancel, so there's not much for us to do here.
|
||||
close_account(account);
|
||||
break;
|
||||
|
||||
case Geary.Account.Problem.SEND_EMAIL_DELIVERY_FAILURE:
|
||||
handle_outbox_failure(StatusBar.Message.OUTBOX_SEND_FAILURE);
|
||||
break;
|
||||
private void report_problem(Geary.ProblemReport report) {
|
||||
debug("Problem reported: %s", report.to_string());
|
||||
|
||||
case Geary.Account.Problem.SEND_EMAIL_SAVE_FAILED:
|
||||
if (!(report.error is IOError.CANCELLED)) {
|
||||
if (report.problem_type == Geary.ProblemType.SEND_EMAIL_SAVE_FAILED) {
|
||||
handle_outbox_failure(StatusBar.Message.OUTBOX_SAVE_SENT_MAIL_FAILED);
|
||||
break;
|
||||
|
||||
case Geary.Account.Problem.CONNECTION_FAILURE:
|
||||
ErrorDialog dialog = new ErrorDialog(main_window,
|
||||
_("Error connecting to the server"),
|
||||
_("Geary encountered an error while connecting to the server. Please try again in a few moments."));
|
||||
dialog.run();
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
} else {
|
||||
MainWindowInfoBar info_bar = new MainWindowInfoBar.for_problem(report);
|
||||
info_bar.retry.connect(on_retry_problem);
|
||||
this.main_window.show_infobar(info_bar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void on_retry_problem(MainWindowInfoBar info_bar) {
|
||||
Geary.ServiceProblemReport? service_report =
|
||||
info_bar.report as Geary.ServiceProblemReport;
|
||||
Error retry_err = null;
|
||||
if (service_report != null) {
|
||||
Geary.Account? account = null;
|
||||
try {
|
||||
account = this.application.engine.get_account_instance(
|
||||
service_report.account
|
||||
);
|
||||
} catch (Error err) {
|
||||
debug("Error getting account for error retry: %s", err.message);
|
||||
}
|
||||
|
||||
if (account != null && account.is_open()) {
|
||||
switch (service_report.service_type) {
|
||||
case Geary.Service.IMAP:
|
||||
account.start_incoming_client.begin((obj, ret) => {
|
||||
try {
|
||||
account.start_incoming_client.end(ret);
|
||||
} catch (Error err) {
|
||||
retry_err = err;
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case Geary.Service.SMTP:
|
||||
account.start_outgoing_client.begin((obj, ret) => {
|
||||
try {
|
||||
account.start_outgoing_client.end(ret);
|
||||
} catch (Error err) {
|
||||
retry_err = err;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
if (retry_err != null) {
|
||||
report_problem(
|
||||
new Geary.ServiceProblemReport(
|
||||
Geary.ProblemType.GENERIC_ERROR,
|
||||
service_report.account,
|
||||
service_report.service_type,
|
||||
retry_err
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handle_outbox_failure(StatusBar.Message message) {
|
||||
bool activate_message = false;
|
||||
try {
|
||||
|
|
@ -949,7 +977,11 @@ public class GearyController : Geary.BaseObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void on_report_problem(Geary.Account account, Geary.ProblemReport problem) {
|
||||
report_problem(problem);
|
||||
}
|
||||
|
||||
private void on_account_email_removed(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier> ids) {
|
||||
if (folder.special_folder_type == Geary.SpecialFolderType.OUTBOX) {
|
||||
main_window.status_bar.deactivate_message(StatusBar.Message.OUTBOX_SEND_FAILURE);
|
||||
|
|
@ -2820,5 +2852,5 @@ public class GearyController : Geary.BaseObject {
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
324
src/client/components/main-window-info-bar.vala
Normal file
324
src/client/components/main-window-info-bar.vala
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Copyright 2017 Michael Gratton <mike@vee.net>
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Displays application-wide or important account-related messages.
|
||||
*/
|
||||
[GtkTemplate (ui = "/org/gnome/Geary/main-window-info-bar.ui")]
|
||||
public class MainWindowInfoBar : Gtk.InfoBar {
|
||||
|
||||
|
||||
private enum ResponseType { COPY, DETAILS, RETRY; }
|
||||
|
||||
/** If reporting a problem, returns the problem report else null. */
|
||||
public Geary.ProblemReport? report { get; private set; default = null; }
|
||||
|
||||
/** Emitted when the user clicks the Retry button, if any. */
|
||||
public signal void retry();
|
||||
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.Label title;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.Label description;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.Grid problem_details;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.TextView detail_text;
|
||||
|
||||
|
||||
public MainWindowInfoBar.for_problem(Geary.ProblemReport report) {
|
||||
Gtk.MessageType type = Gtk.MessageType.WARNING;
|
||||
string title = "";
|
||||
string descr = "";
|
||||
string? retry = null;
|
||||
bool show_generic = false;
|
||||
bool show_close = false;
|
||||
|
||||
if (report is Geary.ServiceProblemReport) {
|
||||
Geary.ServiceProblemReport service_report = (Geary.ServiceProblemReport) report;
|
||||
Geary.Endpoint endpoint = service_report.endpoint;
|
||||
string account = service_report.account.display_name;
|
||||
string server = endpoint.remote_address.hostname;
|
||||
|
||||
if (report.problem_type == Geary.ProblemType.CONNECTION_ERROR &&
|
||||
service_report.service_type == Geary.Service.IMAP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("Problem connecting to incoming server for %s".printf(account));
|
||||
// Translators: String substitution is the server name
|
||||
descr = _("Could not connect to %s, check your Internet access and the server name and try again").printf(server);
|
||||
retry = _("Retry connecting now");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.CONNECTION_ERROR &&
|
||||
service_report.service_type == Geary.Service.SMTP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("Problem connecting to outgoing server for %s".printf(account));
|
||||
// Translators: String substitution is the server name
|
||||
descr = _("Could not connect to %s, check your Internet access and the server name and try again").printf(server);
|
||||
retry = _("Try reconnecting now");
|
||||
retry = _("Retry connecting now");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.NETWORK_ERROR &&
|
||||
service_report.service_type == Geary.Service.IMAP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("Problem with connection to incoming server for %s").printf(account);
|
||||
// Translators: String substitution is the server name
|
||||
descr = _("Network error talking to %s, check your Internet access try again").printf(server);
|
||||
retry = _("Try reconnecting");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.NETWORK_ERROR &&
|
||||
service_report.service_type == Geary.Service.SMTP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("Problem with connection to outgoing server for %s").printf(account);
|
||||
// Translators: String substitution is the server name
|
||||
descr = _("Network error talking to %s, check your Internet access try again").printf(server);
|
||||
retry = _("Try reconnecting");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.SERVER_ERROR &&
|
||||
service_report.service_type == Geary.Service.IMAP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("Problem communicating with incoming server for %s").printf(account);
|
||||
// Translators: String substitution is the server name
|
||||
descr = _("Geary did not understand a message from %s or vice versa, please file a bug report").printf(server);
|
||||
retry = _("Try reconnecting");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.SERVER_ERROR &&
|
||||
service_report.service_type == Geary.Service.SMTP) {
|
||||
title = _("Problem communicating with outgoing mail server");
|
||||
// Translators: First string substitution is the server
|
||||
// name, second is the account name
|
||||
descr = _("Could now communicate with %s for %s, server name and try again in a moment").printf(server, account);
|
||||
retry = _("Try reconnecting");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.LOGIN_FAILED &&
|
||||
service_report.service_type == Geary.Service.IMAP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("Incoming mail server password required for %s").printf(account);
|
||||
descr = _("Messages cannot be received without the correct password.");
|
||||
retry = _("Retry receiving email, you will be prompted for a password");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.LOGIN_FAILED &&
|
||||
service_report.service_type == Geary.Service.SMTP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("Outgoing mail server password required for %s").printf(account);
|
||||
descr = _("Messages cannot be sent without the correct password.");
|
||||
retry = _("Retry sending queued messages, you will be prompted for a password");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.GENERIC_ERROR &&
|
||||
service_report.service_type == Geary.Service.IMAP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("A problem occurred checking mail for %s").printf(account);
|
||||
descr = _("Something went wrong, please file a bug report if the problem persists");
|
||||
retry = _("Try reconnecting");
|
||||
|
||||
} else if (report.problem_type == Geary.ProblemType.GENERIC_ERROR &&
|
||||
service_report.service_type == Geary.Service.SMTP) {
|
||||
// Translators: String substitution is the account name
|
||||
title = _("A problem occurred sending mail for %s").printf(account);
|
||||
descr = _("Something went wrong, please file a bug report if the problem persists");
|
||||
retry = _("Retry sending queued messages");
|
||||
|
||||
} else {
|
||||
debug("Un-handled service problem report: %s".printf(report.to_string()));
|
||||
show_generic = true;
|
||||
}
|
||||
} else if (report is Geary.AccountProblemReport) {
|
||||
Geary.AccountProblemReport account_report = (Geary.AccountProblemReport) report;
|
||||
string account = account_report.account.display_name;
|
||||
if (report.problem_type == Geary.ProblemType.DATABASE_FAILURE) {
|
||||
type = Gtk.MessageType.ERROR;
|
||||
title = _("A database problem has occurred");
|
||||
// Translators: String substitution is the account name
|
||||
descr = _("Messages for %s must be downloaded again.").printf(account);
|
||||
show_close = true;
|
||||
|
||||
} else {
|
||||
debug("Un-handled account problem report: %s".printf(report.to_string()));
|
||||
show_generic = true;
|
||||
}
|
||||
} else {
|
||||
debug("Un-handled generic problem report: %s".printf(report.to_string()));
|
||||
show_generic = true;
|
||||
}
|
||||
|
||||
if (show_generic) {
|
||||
title = _("Geary has encountered a problem");
|
||||
descr = _("Please check the technical details and report the problem if it persists.");
|
||||
show_close = true;
|
||||
}
|
||||
|
||||
this(type, title, descr, show_close);
|
||||
this.report = report;
|
||||
|
||||
if (this.report.error != null) {
|
||||
Gtk.Button details = add_button(_("_Details"), ResponseType.DETAILS);
|
||||
details.tooltip_text = _("View technical details about the error");
|
||||
}
|
||||
|
||||
if (retry != null) {
|
||||
Gtk.Button retry_btn = add_button(_("_Retry"), ResponseType.RETRY);
|
||||
retry_btn.tooltip_text = retry;
|
||||
}
|
||||
}
|
||||
|
||||
protected MainWindowInfoBar(Gtk.MessageType type,
|
||||
string title,
|
||||
string description,
|
||||
bool show_close) {
|
||||
this.message_type = type;
|
||||
this.title.label = title;
|
||||
|
||||
// Set the label and tooltip for the description in case it is
|
||||
// long enough to be ellipsized
|
||||
this.description.label = description;
|
||||
this.description.tooltip_text = description;
|
||||
|
||||
this.show_close_button = show_close;
|
||||
}
|
||||
|
||||
private string format_details() {
|
||||
Geary.ServiceProblemReport? service_report = this.report as Geary.ServiceProblemReport;
|
||||
Geary.AccountProblemReport? account_report = this.report as Geary.AccountProblemReport;
|
||||
|
||||
StringBuilder details = new StringBuilder();
|
||||
details.append_printf(
|
||||
"Geary version: %s\n",
|
||||
GearyApplication.VERSION
|
||||
);
|
||||
details.append_printf(
|
||||
"GTK version: %u.%u.%u\n",
|
||||
Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version()
|
||||
);
|
||||
details.append_printf(
|
||||
"Desktop: %s\n",
|
||||
Environment.get_variable("XDG_CURRENT_DESKTOP") ?? "Unknown"
|
||||
);
|
||||
details.append_printf(
|
||||
"Problem type: %s\n",
|
||||
this.report.problem_type.to_string()
|
||||
);
|
||||
if (account_report != null) {
|
||||
details.append_printf(
|
||||
"Account type: %s\n",
|
||||
account_report.account.service_provider.to_string()
|
||||
);
|
||||
}
|
||||
if (service_report != null) {
|
||||
details.append_printf(
|
||||
"Service type: %s\n",
|
||||
service_report.service_type.to_string()
|
||||
);
|
||||
details.append_printf(
|
||||
"Endpoint: %s\n",
|
||||
service_report.endpoint.to_string()
|
||||
);
|
||||
}
|
||||
if (this.report.error == null) {
|
||||
details.append("No error reported");
|
||||
} else {
|
||||
details.append_printf("Error type: %s\n", this.report.format_error_type());
|
||||
details.append_printf("Message: %s\n", this.report.error.message);
|
||||
}
|
||||
if (this.report.backtrace != null) {
|
||||
details.append("Back trace:\n");
|
||||
foreach (Geary.ProblemReport.StackFrame frame in this.report.backtrace) {
|
||||
details.append_printf(" - %s\n", frame.to_string());
|
||||
}
|
||||
}
|
||||
return details.str;
|
||||
}
|
||||
|
||||
private void show_details() {
|
||||
this.detail_text.buffer.text = format_details();
|
||||
|
||||
// Would love to construct the dialog in Builder, but we to
|
||||
// construct the dialog manually since we can't adjust the
|
||||
// Headerbar setting afterwards. If the user re-clicks on the
|
||||
// Details button to re-show it, a whole bunch of GTK | ||||