[gnome-software: 4/5] gs-external-appstream-utils: Use a separate error domain




commit 794bc702264353b41591f67fd1490088e183b9c0
Author: Philip Withnall <pwithnall endlessos org>
Date:   Mon Feb 28 12:45:19 2022 +0000

    gs-external-appstream-utils: Use a separate error domain
    
    This allows better distinction between errors while downloading the
    appstream data, and errors while installing it system-wide. It also
    better separates the external appstream utils from the unrelated
    `GsPlugin` API.
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>
    
    Helps: #1472

 lib/gs-external-appstream-utils.c | 43 ++++++++++++++++++++++++++++-----------
 lib/gs-external-appstream-utils.h | 19 +++++++++++++++++
 lib/gs-plugin-loader.c            | 26 ++++++++++++++++++++++-
 3 files changed, 75 insertions(+), 13 deletions(-)
---
diff --git a/lib/gs-external-appstream-utils.c b/lib/gs-external-appstream-utils.c
index 3914618d2..0b5cbccd2 100644
--- a/lib/gs-external-appstream-utils.c
+++ b/lib/gs-external-appstream-utils.c
@@ -56,6 +56,8 @@
 
 #define APPSTREAM_SYSTEM_DIR LOCALSTATEDIR "/cache/app-info/xmls"
 
+G_DEFINE_QUARK (gs-external-appstream-error-quark, gs_external_appstream_error)
+
 gchar *
 gs_external_appstream_utils_get_file_cache_path (const gchar *file_name)
 {
@@ -157,9 +159,9 @@ refresh_url_async (GSettings           *settings,
        hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1, url, -1);
        if (hash == NULL) {
                g_task_return_new_error (task,
-                                        GS_PLUGIN_ERROR,
-                                        GS_PLUGIN_ERROR_FAILED,
-                                        "Failed to hash url %s", url);
+                                        GS_EXTERNAL_APPSTREAM_ERROR,
+                                        GS_EXTERNAL_APPSTREAM_ERROR_DOWNLOADING,
+                                        "Failed to hash URI ‘%s’", url);
                return;
        }
        basename = g_strdup_printf ("%s-%s", hash, basename_url);
@@ -234,10 +236,17 @@ download_system_cb (GObject      *source_object,
        g_autoptr(GError) local_error = NULL;
 
        if (!gs_download_file_finish (soup_session, result, &local_error)) {
-               g_task_return_new_error (task,
-                                        GS_PLUGIN_ERROR,
-                                        GS_PLUGIN_ERROR_DOWNLOAD_FAILED,
-                                        "%s", local_error->message);
+               if (!g_network_monitor_get_network_available (g_network_monitor_get_default ()))
+                       g_task_return_new_error (task,
+                                                GS_EXTERNAL_APPSTREAM_ERROR,
+                                                GS_EXTERNAL_APPSTREAM_ERROR_NO_NETWORK,
+                                                "External AppStream could not be downloaded due to being 
offline");
+               else
+                       g_task_return_new_error (task,
+                                                GS_EXTERNAL_APPSTREAM_ERROR,
+                                                GS_EXTERNAL_APPSTREAM_ERROR_DOWNLOADING,
+                                                "Server returned no data for external AppStream file: %s",
+                                                local_error->message);
                return;
        }
 
@@ -250,7 +259,10 @@ download_system_cb (GObject      *source_object,
                g_debug ("Installed appstream file %s", g_file_peek_path (tmp_file));
                g_task_return_boolean (task, TRUE);
        } else {
-               g_task_return_error (task, g_steal_pointer (&local_error));
+               g_task_return_new_error (task,
+                                        GS_EXTERNAL_APPSTREAM_ERROR,
+                                        GS_EXTERNAL_APPSTREAM_ERROR_INSTALLING_ON_SYSTEM,
+                                        "Error installing external AppStream file on system: %s", 
local_error->message);
        }
 }
 
@@ -265,10 +277,17 @@ download_user_cb (GObject      *source_object,
        g_autoptr(GError) local_error = NULL;
 
        if (!gs_download_file_finish (soup_session, result, &local_error)) {
-               g_task_return_new_error (task,
-                                        GS_PLUGIN_ERROR,
-                                        GS_PLUGIN_ERROR_DOWNLOAD_FAILED,
-                                        "%s", local_error->message);
+               if (!g_network_monitor_get_network_available (g_network_monitor_get_default ()))
+                       g_task_return_new_error (task,
+                                                GS_EXTERNAL_APPSTREAM_ERROR,
+                                                GS_EXTERNAL_APPSTREAM_ERROR_NO_NETWORK,
+                                                "External AppStream could not be downloaded due to being 
offline");
+               else
+                       g_task_return_new_error (task,
+                                                GS_EXTERNAL_APPSTREAM_ERROR,
+                                                GS_EXTERNAL_APPSTREAM_ERROR_DOWNLOADING,
+                                                "Server returned no data for external AppStream file: %s",
+                                                local_error->message);
                return;
        }
 
diff --git a/lib/gs-external-appstream-utils.h b/lib/gs-external-appstream-utils.h
index 2759ca61e..17876114a 100644
--- a/lib/gs-external-appstream-utils.h
+++ b/lib/gs-external-appstream-utils.h
@@ -17,6 +17,25 @@
 
 #define EXTERNAL_APPSTREAM_PREFIX "org.gnome.Software"
 
+/**
+ * GsExternalAppstreamError:
+ * @GS_EXTERNAL_APPSTREAM_ERROR_DOWNLOADING: Error while downloading external appstream data.
+ * @GS_EXTERNAL_APPSTREAM_ERROR_NO_NETWORK: Offline or network unavailable.
+ * @GS_EXTERNAL_APPSTREAM_ERROR_INSTALLING_ON_SYSTEM: Error while installing an external AppStream file 
system-wide.
+ *
+ * Error codes for external appstream operations.
+ *
+ * Since: 42
+ */
+typedef enum {
+       GS_EXTERNAL_APPSTREAM_ERROR_DOWNLOADING,
+       GS_EXTERNAL_APPSTREAM_ERROR_NO_NETWORK,
+       GS_EXTERNAL_APPSTREAM_ERROR_INSTALLING_ON_SYSTEM,
+} GsExternalAppstreamError;
+
+#define GS_EXTERNAL_APPSTREAM_ERROR gs_external_appstream_error_quark ()
+GQuark          gs_external_appstream_error_quark (void);
+
 const gchar    *gs_external_appstream_utils_get_system_dir (void);
 gchar          *gs_external_appstream_utils_get_file_cache_path (const gchar   *file_name);
 void            gs_external_appstream_refresh_async (guint64                     cache_age_secs,
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index abccfc2a1..48e84b985 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -916,6 +916,7 @@ gs_plugin_loader_run_results (GsPluginLoaderHelper *helper,
                g_autoptr(GsApp) app_dl = NULL;
                RefreshProgressData progress_data;
                g_autoptr(GAsyncResult) external_appstream_result = NULL;
+               g_autoptr(GError) local_error = NULL;
 
                app_dl = gs_app_new ("external-appstream");
                gs_app_set_summary_missing (app_dl,
@@ -937,8 +938,31 @@ gs_plugin_loader_run_results (GsPluginLoaderHelper *helper,
                while (external_appstream_result == NULL)
                        g_main_context_iteration (g_main_context_get_thread_default (), TRUE);
 
-               if (!gs_external_appstream_refresh_finish (external_appstream_result, error))
+               if (!gs_external_appstream_refresh_finish (external_appstream_result, &local_error)) {
+                       /* Don’t fail updates if the external AppStream server is unavailable */
+                       if (g_error_matches (local_error, GS_EXTERNAL_APPSTREAM_ERROR,
+                                            GS_EXTERNAL_APPSTREAM_ERROR_DOWNLOADING) ||
+                           g_error_matches (local_error, GS_EXTERNAL_APPSTREAM_ERROR,
+                                            GS_EXTERNAL_APPSTREAM_ERROR_NO_NETWORK)) {
+                               g_autoptr(GsPluginEvent) event = NULL;
+
+                               event = gs_plugin_event_new ("error", local_error,
+                                                            "action", GS_PLUGIN_ACTION_DOWNLOAD,
+                                                            NULL);
+
+                               if (gs_plugin_job_get_interactive (helper->plugin_job))
+                                       gs_plugin_event_add_flag (event, GS_PLUGIN_EVENT_FLAG_INTERACTIVE);
+                               else
+                                       gs_plugin_event_add_flag (event, GS_PLUGIN_EVENT_FLAG_WARNING);
+                               gs_plugin_loader_add_event (plugin_loader, event);
+
+                               return TRUE;
+                       }
+
+                       g_propagate_error (error, g_steal_pointer (&local_error));
+
                        return FALSE;
+               }
        }
 #endif
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]