diff --git a/src/server/app.py b/src/server/app.py index 10ae6ee..a12f263 100644 --- a/src/server/app.py +++ b/src/server/app.py @@ -9,6 +9,8 @@ from __future__ import annotations import os from pathlib import Path +import json + from flask import Flask, Response, jsonify, request, send_file from server import http_api @@ -94,11 +96,19 @@ def create_app() -> Flask: "queryStringParameters": qs or None, } result = http_api.lambda_handler(event, None) - return Response( - result["body"], - status=result["statusCode"], - headers=result.get("headers") or {"Content-Type": "application/json"}, - ) + try: + payload = json.loads(result["body"]) + except (TypeError, KeyError, json.JSONDecodeError): + resp = jsonify({"error": "Internal error"}) + resp.status_code = 500 + return resp + if not isinstance(payload, dict): + resp = jsonify({"error": "Internal error"}) + resp.status_code = 500 + return resp + resp = jsonify(payload) + resp.status_code = int(result.get("statusCode") or 500) + return resp @app.route("/api/", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"]) def api(rest: str): diff --git a/src/server/worker.py b/src/server/worker.py index 8ae9dca..524e297 100644 --- a/src/server/worker.py +++ b/src/server/worker.py @@ -48,8 +48,9 @@ def main() -> None: try: payload = json.loads(msg["Body"]) result = run_job(payload) - logger.info("job result %s", result) - if result.get("status") == "skipped": + status = result.get("status") if isinstance(result, dict) else None + logger.info("job event=%s status=%s", payload.get("event"), status) + if status == "skipped": # Leave the message visible after timeout so a later # receive can run it. Deleting here dropped the only # weekly close/reminder when delivery landed late. diff --git a/tests/test_app.py b/tests/test_app.py index bc07a50..77661a4 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -29,3 +29,19 @@ def test_options_preflight_from_portal_origin(): == "https://internal.seahaven.com" ) assert "Authorization" in response.headers["Access-Control-Allow-Headers"] + + +def test_api_dispatch_jsonifies_handler_body(): + from unittest.mock import patch + + with patch("server.http_api.lambda_handler") as mock_handler: + mock_handler.return_value = { + "statusCode": 400, + "headers": {"Content-Type": "application/json"}, + "body": '{"error": "Bad request"}', + } + client = create_app().test_client() + response = client.get("/api/menu") + assert response.status_code == 400 + assert response.get_json() == {"error": "Bad request"} + assert response.content_type.startswith("application/json")