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
This commit is contained in:
Jelle Spijker 2021-12-08 09:58:53 +01:00
parent 6c976bc9b0
commit 453de95d12
No known key found for this signature in database
GPG key ID: 6662DC033BE6B99A
2 changed files with 17 additions and 6 deletions

View file

@ -95,10 +95,16 @@ class LocalPackageList(PackageList):
if len(response_data["data"]) == 0: if len(response_data["data"]) == 0:
return return
for package_data in response_data["data"]: try:
package = self.getPackageModel(package_data["package_id"]) for package_data in response_data["data"]:
package.download_url = package_data.get("download_url", "") package = self.getPackageModel(package_data["package_id"])
package.can_update = True package.download_url = package_data.get("download_url", "")
package.can_update = True
self.sort(attrgetter("sectionTitle", "can_update", "displayName"), key = "package", reverse = True) self.sort(attrgetter("sectionTitle", "can_update", "displayName"), key = "package", reverse = True)
self._ongoing_requests["check_updates"] = None 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

View file

@ -218,6 +218,11 @@ class PackageList(ListModel):
Logger.error(f"Failed to write downloaded package to temp file {e}") Logger.error(f"Failed to write downloaded package to temp file {e}")
temp_file.close() temp_file.close()
self._downloadError(package_id, update) 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: def _downloadError(self, package_id: str, update: bool = False, reply: Optional["QNetworkReply"] = None, error: Optional["QNetworkReply.NetworkError"] = None) -> None:
if reply: if reply: