From 4e55234453ddae953c01fb49b5d5959d31ea7af7 Mon Sep 17 00:00:00 2001 From: Miikka Kallio Date: Thu, 6 Feb 2025 12:20:45 +0200 Subject: [PATCH 1/2] Re-enable validation after an error occurs Re-enables validation button and hides progress bar if a the validation lambda call fails. --- arho_feature_template/core/lambda_service.py | 16 +++++++++----- .../gui/docks/validation_dock.py | 22 +++++++++++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/arho_feature_template/core/lambda_service.py b/arho_feature_template/core/lambda_service.py index c32171a..c9e6503 100644 --- a/arho_feature_template/core/lambda_service.py +++ b/arho_feature_template/core/lambda_service.py @@ -15,6 +15,7 @@ class LambdaService(QObject): jsons_received = pyqtSignal(dict, dict) validation_received = pyqtSignal(dict) + validation_failed = pyqtSignal() ActionAttribute = cast(QNetworkRequest.Attribute, QNetworkRequest.User + 1) ACTION_VALIDATE_PLANS = "validate_plans" ACTION_GET_PLANS = "get_plans" @@ -58,9 +59,12 @@ def _is_api_gateway_request(self) -> bool: return bool(match) def _handle_reply(self, reply: QNetworkReply): + action = reply.request().attribute(LambdaService.ActionAttribute) if reply.error() != QNetworkReply.NoError: error = reply.errorString() - QMessageBox.critical(None, "API Error", f"Lambda call failed: {error}") + QMessageBox.critical(None, "API Virhe", f"Lambda kutsu epäonnistui: {error}") + if action == self.ACTION_VALIDATE_PLANS: + self.validation_failed.emit() reply.deleteLater() return @@ -72,7 +76,9 @@ def _handle_reply(self, reply: QNetworkReply): # If calling the lambda directly, the response includes status code and body if int(response_json.get("statusCode", 0)) != HTTPStatus.OK: error = response_json["body"] if "body" in response_json else response_json["errorMessage"] - QMessageBox.critical(None, "API Error", f"Lambda call failed: {error}") + QMessageBox.critical(None, "API Virhe", f"Lambda kutsu epäonnistui: {error}") + if action == self.ACTION_VALIDATE_PLANS: + self.validation_failed.emit() reply.deleteLater() return body = response_json["body"] @@ -80,12 +86,13 @@ def _handle_reply(self, reply: QNetworkReply): body = response_json except (json.JSONDecodeError, KeyError) as e: - QMessageBox.critical(None, "JSON Error", f"Failed to parse response JSON: {e}") + QMessageBox.critical(None, "JSON Virhe", f"Vastauksen JSON-tiedoston jäsennys epäonnistui: {e}") + if action == self.ACTION_VALIDATE_PLANS: + self.validation_failed.emit() return finally: reply.deleteLater() - action = reply.request().attribute(LambdaService.ActionAttribute) if action == self.ACTION_GET_PLANS: self._process_json_reply(body) elif action == self.ACTION_VALIDATE_PLANS: @@ -95,7 +102,6 @@ def _process_validation_reply(self, response_json: dict): """Processes the validation reply from the lambda and emits a signal.""" validation_errors = response_json.get("ryhti_responses") - self.validation_received.emit(validation_errors) def _process_json_reply(self, response_json: dict): diff --git a/arho_feature_template/gui/docks/validation_dock.py b/arho_feature_template/gui/docks/validation_dock.py index 9658d1c..575df9f 100644 --- a/arho_feature_template/gui/docks/validation_dock.py +++ b/arho_feature_template/gui/docks/validation_dock.py @@ -29,6 +29,7 @@ def __init__(self, parent=None): self.lambda_service = LambdaService() self.lambda_service.validation_received.connect(self.list_validation_errors) + self.lambda_service.validation_failed.connect(self.enable_validation) self.validate_button.clicked.connect(self.validate) def validate(self): @@ -48,15 +49,25 @@ def validate(self): self.lambda_service.validate_plan(active_plan_id) + def enable_validation(self): + """Hide progress bar and re-enable the button""" + self.progress_bar.setVisible(False) + self.validate_button.setEnabled(True) + self.validation_result_tree_view.expandAll() + self.validation_result_tree_view.resizeColumnToContents(0) + def list_validation_errors(self, validation_json): """Slot for listing validation errors and warnings.""" + if not validation_json: iface.messageBar().pushMessage("Virhe", "Validaatio json puuttuu.", level=1) + self.enable_validation() return - if not validation_json: - # If no errors or warnings, display a message and exit + # If no errors or warnings, display a message and exit + if not any(validation_json.values()): iface.messageBar().pushMessage("Virhe", "Ei virheitä havaittu.", level=1) + self.enable_validation() return for error_data in validation_json.values(): @@ -79,8 +90,5 @@ def list_validation_errors(self, validation_json): warning.get("message", ""), ) - # Hide progress bar and re-enable the button - self.progress_bar.setVisible(False) - self.validate_button.setEnabled(True) - self.validation_result_tree_view.expandAll() - self.validation_result_tree_view.resizeColumnToContents(0) + # Always enable validation at the end + self.enable_validation() From 4db772fd737ad96f89b63f135b878e5a59978e77 Mon Sep 17 00:00:00 2001 From: Lauri Kajan Date: Thu, 13 Feb 2025 18:23:36 +0200 Subject: [PATCH 2/2] Refactor --- arho_feature_template/core/lambda_service.py | 34 +++++++++++++------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/arho_feature_template/core/lambda_service.py b/arho_feature_template/core/lambda_service.py index c9e6503..afe0898 100644 --- a/arho_feature_template/core/lambda_service.py +++ b/arho_feature_template/core/lambda_service.py @@ -3,7 +3,7 @@ import json import re from http import HTTPStatus -from typing import cast +from typing import Callable, cast from qgis.PyQt.QtCore import QByteArray, QObject, QUrl, pyqtSignal from qgis.PyQt.QtNetwork import QNetworkAccessManager, QNetworkProxy, QNetworkReply, QNetworkRequest @@ -58,13 +58,28 @@ def _is_api_gateway_request(self) -> bool: match = re.match(r"^https://.*execute-api.*amazonaws\.com.*$", self.lambda_url) return bool(match) + def _get_response_handler(self, action: str) -> Callable[[dict], None]: + handlers = { + self.ACTION_GET_PLANS: self._process_json_reply, + self.ACTION_VALIDATE_PLANS: self._process_validation_reply, + } + return handlers[action] + + def _get_error_handler(self, action: str) -> Callable[[], None]: + handlers = { + self.ACTION_GET_PLANS: lambda: None, + self.ACTION_VALIDATE_PLANS: self._handle_validation_error, + } + return handlers[action] + def _handle_reply(self, reply: QNetworkReply): action = reply.request().attribute(LambdaService.ActionAttribute) + response_handler = self._get_response_handler(action) + error_handler = self._get_error_handler(action) if reply.error() != QNetworkReply.NoError: error = reply.errorString() QMessageBox.critical(None, "API Virhe", f"Lambda kutsu epäonnistui: {error}") - if action == self.ACTION_VALIDATE_PLANS: - self.validation_failed.emit() + error_handler() reply.deleteLater() return @@ -77,8 +92,7 @@ def _handle_reply(self, reply: QNetworkReply): if int(response_json.get("statusCode", 0)) != HTTPStatus.OK: error = response_json["body"] if "body" in response_json else response_json["errorMessage"] QMessageBox.critical(None, "API Virhe", f"Lambda kutsu epäonnistui: {error}") - if action == self.ACTION_VALIDATE_PLANS: - self.validation_failed.emit() + error_handler() reply.deleteLater() return body = response_json["body"] @@ -87,16 +101,14 @@ def _handle_reply(self, reply: QNetworkReply): except (json.JSONDecodeError, KeyError) as e: QMessageBox.critical(None, "JSON Virhe", f"Vastauksen JSON-tiedoston jäsennys epäonnistui: {e}") - if action == self.ACTION_VALIDATE_PLANS: - self.validation_failed.emit() + error_handler() return finally: reply.deleteLater() + response_handler(body) - if action == self.ACTION_GET_PLANS: - self._process_json_reply(body) - elif action == self.ACTION_VALIDATE_PLANS: - self._process_validation_reply(body) + def _handle_validation_error(self): + self.validation_failed.emit() def _process_validation_reply(self, response_json: dict): """Processes the validation reply from the lambda and emits a signal."""