From 453de95d12d93dcbf013dbaa2677590521064cc1 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Wed, 8 Dec 2021 09:58:53 +0100 Subject: [PATCH] Defensive programming Long API calls might return after the Local or Remote PackageList has been deconstructed. Somehow setting the ownership in QML doesn't seem to work for this. So we guard against this with a try catch block. Contributes to: CURA-8587 --- plugins/Marketplace/LocalPackageList.py | 18 ++++++++++++------ plugins/Marketplace/PackageList.py | 5 +++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/plugins/Marketplace/LocalPackageList.py b/plugins/Marketplace/LocalPackageList.py index c3491fc3af..6fb9cfbf34 100644 --- a/plugins/Marketplace/LocalPackageList.py +++ b/plugins/Marketplace/LocalPackageList.py @@ -95,10 +95,16 @@ class LocalPackageList(PackageList): if len(response_data["data"]) == 0: return - for package_data in response_data["data"]: - package = self.getPackageModel(package_data["package_id"]) - package.download_url = package_data.get("download_url", "") - package.can_update = True + try: + for package_data in response_data["data"]: + package = self.getPackageModel(package_data["package_id"]) + package.download_url = package_data.get("download_url", "") + package.can_update = True - self.sort(attrgetter("sectionTitle", "can_update", "displayName"), key = "package", reverse = True) - self._ongoing_requests["check_updates"] = None + self.sort(attrgetter("sectionTitle", "can_update", "displayName"), key = "package", reverse = True) + self._ongoing_requests["check_updates"] = None + except RuntimeError: + # Setting the ownership of this object to not qml can still result in a RuntimeError. Which can occur when quickly toggling + # between de-/constructing RemotePackageLists. This try-except is here to prevent a hard crash when the wrapped C++ object + # was deleted when it was still parsing the response + return diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py index a2c67dc1ef..7e64373e9c 100644 --- a/plugins/Marketplace/PackageList.py +++ b/plugins/Marketplace/PackageList.py @@ -218,6 +218,11 @@ class PackageList(ListModel): Logger.error(f"Failed to write downloaded package to temp file {e}") temp_file.close() self._downloadError(package_id, update) + except RuntimeError: + # Setting the ownership of this object to not qml can still result in a RuntimeError. Which can occur when quickly toggling + # between de-/constructing Remote or Local PackageLists. This try-except is here to prevent a hard crash when the wrapped C++ object + # was deleted when it was still parsing the response + return def _downloadError(self, package_id: str, update: bool = False, reply: Optional["QNetworkReply"] = None, error: Optional["QNetworkReply.NetworkError"] = None) -> None: if reply: