diff --git a/zbiorka_app/errors.py b/zbiorka_app/errors.py index d8633b0..6592a71 100644 --- a/zbiorka_app/errors.py +++ b/zbiorka_app/errors.py @@ -1,4 +1,3 @@ -from html import escape from http import HTTPStatus from flask import jsonify, render_template, request @@ -6,20 +5,21 @@ from jinja2 import TemplateNotFound from sqlalchemy.exc import OperationalError from werkzeug.exceptions import HTTPException -from .utils import safe_db_rollback +from .extensions import db -JSON_MIMETYPES = ["application/json", "text/html"] +def _safe_rollback() -> None: + try: + db.session.rollback() + except Exception: + pass def _wants_json_response() -> bool: if request.path.startswith("/api/"): return True - if request.is_json: - return True - - best = request.accept_mimetypes.best_match(JSON_MIMETYPES) + best = request.accept_mimetypes.best_match(["application/json", "text/html"]) if not best: return False @@ -30,43 +30,49 @@ def _wants_json_response() -> bool: ) -def _status_phrase(status_code: int) -> str: +def _get_status_phrase(status_code: int) -> str: try: return HTTPStatus(status_code).phrase except ValueError: return "Blad" -def _status_description(status_code: int) -> str: +def _get_status_description(status_code: int) -> str: try: return HTTPStatus(status_code).description except ValueError: return "Wystapil blad podczas przetwarzania zadania." -def _plain_fallback(status_code: int, phrase: str, description: str): - html = f""" - - - - - {status_code} {escape(phrase)} - - -

{status_code} - {escape(phrase)}

-

{escape(description)}

- -""" - return html, status_code +def _error_headers(status_code: int) -> dict[str, str]: + headers = {} + + if status_code >= 500: + headers.update( + { + "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0, private", + "Pragma": "no-cache", + "Expires": "0", + "Surrogate-Control": "no-store", + } + ) + + return headers def _render_error(status_code: int, message: str | None = None): - phrase = _status_phrase(status_code) - description = message or _status_description(status_code) - payload = {"status": status_code, "error": phrase, "message": description} + phrase = _get_status_phrase(status_code) + description = message or _get_status_description(status_code) + headers = _error_headers(status_code) + + payload = { + "status": status_code, + "error": phrase, + "message": description, + } if _wants_json_response(): - return jsonify(payload), status_code + return jsonify(payload), status_code, headers try: return ( @@ -77,11 +83,14 @@ def _render_error(status_code: int, message: str | None = None): error_message=description, ), status_code, + headers, ) except TemplateNotFound: - return _plain_fallback(status_code, phrase, description) - except Exception: - return _plain_fallback(status_code, phrase, description) + return ( + f"{status_code} {phrase}: {description}", + status_code, + headers, + ) def register_error_handlers(app): @@ -91,12 +100,15 @@ def register_error_handlers(app): @app.errorhandler(OperationalError) def handle_operational_error(exc): - safe_db_rollback() + _safe_rollback() app.logger.exception("Blad polaczenia z baza danych: %s", exc) - return _render_error(503, "Baza danych jest chwilowo niedostepna. Sprobuj ponownie za chwile.") + return _render_error( + 503, + "Baza danych jest chwilowo niedostepna. Sprobuj ponownie za chwile.", + ) @app.errorhandler(Exception) def handle_unexpected_error(exc): - safe_db_rollback() + _safe_rollback() app.logger.exception("Nieobsluzony wyjatek: %s", exc) - return _render_error(500, "Wystapil nieoczekiwany blad serwera.") + return _render_error(500, "Wystapil nieoczekiwany blad serwera.") \ No newline at end of file diff --git a/zbiorka_app/templates/error.html b/zbiorka_app/templates/error.html index 8789618..c0ef015 100644 --- a/zbiorka_app/templates/error.html +++ b/zbiorka_app/templates/error.html @@ -1,21 +1,75 @@ -{% extends "base.html" %} + + + + + {{ error_code }} {{ error_name }} + -{% block title %}{{ error_code }} {{ error_name }}{% endblock %} + {% if asset_url is defined %} + + {% else %} + + {% endif %} -{% block content %} -
-
-
-
-
{{ error_code }}
-

{{ error_name }}

-

{{ error_message }}

- + + + +
+
+
{{ error_code }}
+

{{ error_name }}

+

{{ error_message }}

+ + -
-
-
-{% endblock %} + + + + \ No newline at end of file