From 455f9b32b00a53a95cf28c2d9d110d045e4c3c50 Mon Sep 17 00:00:00 2001 From: podliashanyk <60876078+podliashanyk@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:33:21 +0100 Subject: [PATCH] Handle 400 Bad Request on event updates (#49) * Upgrade htmx to 1.9.10 * Fix config of htmx extensions * Add generic 400 error message element * Add 400 error handler * Drop using multi-swap extension in modal As due to some bug multi-swap and response-targets extensions do not work together. Response-targets ext is necessary for error handling and is ignored in components that use multi-swap. * Display 400 error message in event update modals --- src/howitz/__init__.py | 5 +- src/howitz/endpoints.py | 19 +++-- src/howitz/error_handlers.py | 7 ++ .../modals/update-event-status-modal.html | 5 ++ .../update-singular-event-status-modal.html | 8 +- src/howitz/templates/includes/configs.html | 3 +- src/howitz/templates/layouts/base.html | 6 +- .../templates/responses/400-generic.html | 5 ++ .../responses/update-event-response.html | 78 ++++++++++++++++++- 9 files changed, 122 insertions(+), 14 deletions(-) create mode 100644 src/howitz/templates/responses/400-generic.html diff --git a/src/howitz/__init__.py b/src/howitz/__init__.py index 12c06333..d4ec35fc 100644 --- a/src/howitz/__init__.py +++ b/src/howitz/__init__.py @@ -7,12 +7,12 @@ from flask.logging import default_handler from flask_assets import Bundle, Environment from flask_login import LoginManager, logout_user -from werkzeug.exceptions import HTTPException +from werkzeug.exceptions import HTTPException, BadRequest from howitz.config.utils import load_config from howitz.config.zino1 import make_zino1_config from howitz.config.howitz import make_howitz_config -from howitz.error_handlers import handle_generic_exception, handle_generic_http_exception +from howitz.error_handlers import handle_generic_exception, handle_generic_http_exception, handle_400 from howitz.users.db import UserDB from howitz.users.commands import user_cli from zinolib.controllers.zino1 import Zino1EventManager @@ -27,6 +27,7 @@ def create_app(test_config=None): # register error handlers app.register_error_handler(Exception, handle_generic_exception) app.register_error_handler(HTTPException, handle_generic_http_exception) + app.register_error_handler(BadRequest, handle_400) # load config app = load_config(app, test_config) diff --git a/src/howitz/endpoints.py b/src/howitz/endpoints.py index cd5305da..3d7519ef 100644 --- a/src/howitz/endpoints.py +++ b/src/howitz/endpoints.py @@ -17,7 +17,8 @@ from datetime import datetime, timezone -from zinolib.controllers.zino1 import Zino1EventManager, RetryError +from werkzeug.exceptions import BadRequest +from zinolib.controllers.zino1 import Zino1EventManager, RetryError, EventClosedError from zinolib.event_types import Event, AdmState, PortState, BFDState, ReachabilityState from zinolib.compat import StrEnum from zinolib.ritz import NotConnectedError @@ -391,8 +392,12 @@ def update_event_status(event_id): new_state = request.form['event-state'] new_history = request.form['event-history'] - if not current_state == new_state: - set_state_res = current_app.event_manager.change_admin_state_for_id(event_id, AdmState(new_state)) + try: + if not current_state == new_state: + set_state_res = current_app.event_manager.change_admin_state_for_id(event_id, AdmState(new_state)) + except EventClosedError as closedErr: + current_app.logger.exception('EventClosedError %s', closedErr) + raise BadRequest(description=closedErr.args[0]) from closedErr if new_history: add_history_res = current_app.event_manager.add_history_entry_for_id(event_id, new_history) @@ -423,8 +428,12 @@ def bulk_update_events_status(): # Update each selected event with new values for event_id in selected_events: - if new_state: - set_state_res = current_app.event_manager.change_admin_state_for_id(int(event_id), AdmState(new_state)) + try: + if new_state: + set_state_res = current_app.event_manager.change_admin_state_for_id(int(event_id), AdmState(new_state)) + except EventClosedError as closedErr: + current_app.logger.exception('EventClosedError %s', closedErr) + raise BadRequest(description=closedErr.args[0]) from closedErr if new_history: add_history_res = current_app.event_manager.add_history_entry_for_id(int(event_id), new_history) diff --git a/src/howitz/error_handlers.py b/src/howitz/error_handlers.py index 6acaaf9f..7f44b4c2 100644 --- a/src/howitz/error_handlers.py +++ b/src/howitz/error_handlers.py @@ -41,3 +41,10 @@ def handle_generic_exception(e): return render_template('/components/popups/alerts/error/error-alert.html', alert_id=alert_random_id, short_err_msg=short_err_msg) + + +def handle_400(e): + current_app.logger.exception("400 Bad Request has occurred %s", e) + + return render_template('/responses/400-generic.html', + err_msg=e.description), 400 diff --git a/src/howitz/templates/components/popups/modals/update-event-status-modal.html b/src/howitz/templates/components/popups/modals/update-event-status-modal.html index bb9374ce..5d31f5e1 100644 --- a/src/howitz/templates/components/popups/modals/update-event-status-modal.html +++ b/src/howitz/templates/components/popups/modals/update-event-status-modal.html @@ -3,6 +3,7 @@ aria-labelledby="modal-title" role="dialog" aria-modal="true" + hx-target-error="body" > diff --git a/src/howitz/templates/components/popups/modals/update-singular-event-status-modal.html b/src/howitz/templates/components/popups/modals/update-singular-event-status-modal.html index 458fc733..d901a243 100644 --- a/src/howitz/templates/components/popups/modals/update-singular-event-status-modal.html +++ b/src/howitz/templates/components/popups/modals/update-singular-event-status-modal.html @@ -3,6 +3,7 @@ aria-labelledby="modal-title" role="dialog" aria-modal="true" + hx-target-error="body" > diff --git a/src/howitz/templates/includes/configs.html b/src/howitz/templates/includes/configs.html index ec156c66..713e64df 100644 --- a/src/howitz/templates/includes/configs.html +++ b/src/howitz/templates/includes/configs.html @@ -1,3 +1,4 @@ - + diff --git a/src/howitz/templates/layouts/base.html b/src/howitz/templates/layouts/base.html index 871c8075..605ce9db 100644 --- a/src/howitz/templates/layouts/base.html +++ b/src/howitz/templates/layouts/base.html @@ -9,8 +9,8 @@ - @@ -24,7 +24,7 @@ {% block content %} {% endblock content %} diff --git a/src/howitz/templates/responses/400-generic.html b/src/howitz/templates/responses/400-generic.html new file mode 100644 index 00000000..9c57aa94 --- /dev/null +++ b/src/howitz/templates/responses/400-generic.html @@ -0,0 +1,5 @@ +

+ Error: {{ err_msg }} +

diff --git a/src/howitz/templates/responses/update-event-response.html b/src/howitz/templates/responses/update-event-response.html index cc9c4689..ac8619da 100644 --- a/src/howitz/templates/responses/update-event-response.html +++ b/src/howitz/templates/responses/update-event-response.html @@ -1,4 +1,78 @@ -{% include "/components/row/expanded-row.html" %} + -
+ {% with padding='px-3 py-2' %} + + {% with color=event.color if event.color %} + {% if is_selected %} + {% include "/components/row/event-checked-box.html" %} + {% else %} + {% include "/components/row/event-unchecked-box.html" %} + {% endif %} + {% endwith %} + + + + {% with event=event %} + {% include "/components/row/data-cells.html" %} + {% endwith %} + + {% with id=id, color=event.color %} + {% include "/components/row/collapse-btn.html" %} + {% endwith %} + + {% endwith %} + + + + + + +
+ +
+ + {% with id=id %} + {% include "/components/accordion/event-actions-buttons.html" %} + {% endwith %} + +
+
+ {% with event_attr=event_attr %} + {% include "/components/accordion/event-attributes.html" %} + {% endwith %} +
+ +
+ {% with id=id, event_msgs=event_msgs %} + {% include "/components/accordion/event-messages-block.html" %} + {% endwith %} +
+
+
+
+ + + +