diff --git a/solstone/convey/utils.py b/solstone/convey/utils.py index c2fb13260..fe20de74f 100644 --- a/solstone/convey/utils.py +++ b/solstone/convey/utils.py @@ -6,7 +6,6 @@ import logging import math import re import secrets -import sys import time from datetime import datetime from pathlib import Path @@ -18,7 +17,6 @@ from solstone.convey.reasons import Reason DATE_RE = re.compile(r"\d{8}") _REQUEST_ID_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ" -_LEGACY_ERROR_RESPONSE_SEEN: set[str] = set() _LOGGER = logging.getLogger("solstone.convey.utils") @@ -249,20 +247,8 @@ def save_json( return False -def _log_legacy_error_response_string_form() -> None: - frame = sys._getframe(2) - key = f"{frame.f_code.co_filename}:{frame.f_lineno}" - if key in _LEGACY_ERROR_RESPONSE_SEEN: - return - _LEGACY_ERROR_RESPONSE_SEEN.add(key) - _LOGGER.warning( - "legacy error_response string form at %s — migrate to Reason", - key, - ) - - def error_response( - reason: Reason | str, + reason: Reason, status: int | None = None, *, detail: str | None = None, @@ -272,29 +258,24 @@ def error_response( Provides consistent error response format across all API endpoints. Args: - reason: Reason constant, or legacy string message during migration + reason: Reason constant status: Optional HTTP status override detail: Optional implementation-specific context Returns: Tuple of (jsonify response, status_code) ready for Flask return """ - if isinstance(reason, Reason): - response_status = status if status is not None else reason.status - return ( - jsonify( - { - "error": reason.message, - "reason_code": reason.code, - "detail": detail or "", - } - ), - response_status, - ) - - _log_legacy_error_response_string_form() - response_status = status if status is not None else 400 - return jsonify({"error": reason}), response_status + response_status = status if status is not None else reason.status + return ( + jsonify( + { + "error": reason.message, + "reason_code": reason.code, + "detail": detail or "", + } + ), + response_status, + ) def error_response_with_reason( diff --git a/tests/test_convey_reasons.py b/tests/test_convey_reasons.py index 59d70963d..31995b67f 100644 --- a/tests/test_convey_reasons.py +++ b/tests/test_convey_reasons.py @@ -1,13 +1,10 @@ # SPDX-License-Identifier: AGPL-3.0-only # Copyright (c) 2026 sol pbc -import logging - from flask import Flask from solstone.convey.reasons import AUTH_REQUIRED, Reason from solstone.convey.utils import ( - _LEGACY_ERROR_RESPONSE_SEEN, error_response, error_response_with_reason, ) @@ -18,11 +15,6 @@ def _app_context(): return app.app_context() -def _legacy_error_response_from_same_site(): - with _app_context(): - return [error_response("legacy", 400) for _ in range(2)] - - def test_reason_status_defaults_to_400(): reason = Reason("test_reason", "Test message.") @@ -61,24 +53,6 @@ def test_error_response_reason_includes_detail(): assert response.get_json()["detail"] == "some detail" -def test_error_response_legacy_shape_and_logs_once(caplog): - _LEGACY_ERROR_RESPONSE_SEEN.clear() - caplog.set_level(logging.WARNING, logger="solstone.convey.utils") - - (first_response, first_status), (second_response, second_status) = ( - _legacy_error_response_from_same_site() - ) - - assert first_status == 400 - assert second_status == 400 - assert first_response.get_json() == {"error": "legacy"} - assert second_response.get_json() == {"error": "legacy"} - assert "reason_code" not in first_response.get_json() - assert "detail" not in first_response.get_json() - assert len(caplog.records) == 1 - assert "legacy error_response string form at" in caplog.records[0].message - - def test_error_response_with_reason_emits_legacy_reason_key(): with _app_context(): response, status = error_response_with_reason(AUTH_REQUIRED, detail="x")