feat: add proper HTTP status codes to all API error responses

- 217 error returns across 18 route files + api.py now use JSONResponse
  with appropriate HTTP status codes instead of returning HTTP 200
- Status code distribution: 500 (121), 400 (39), 503 (28), 404 (24), 409 (3), 502 (2)
- Fixed language.py tuple-return bug (was serializing as JSON array)
- Fixed bare except clauses in bipolar_mode.py and voice.py
- Body-level error schemas preserved (status/error + success/error patterns)
  so web UI continues working without changes
- chat.py (SSE) unchanged: errors sent within stream protocol
- All 170 tests pass
This commit is contained in:
2026-04-15 15:43:18 +03:00
parent 33b2033cc3
commit edc9f27925
19 changed files with 243 additions and 227 deletions

View File

@@ -3,6 +3,7 @@
import os
import json
from fastapi import APIRouter
from fastapi.responses import JSONResponse
import globals
from server_manager import server_manager
from routes.models import ServerConfigRequest
@@ -63,7 +64,7 @@ def add_server(data: ServerConfigRequest):
server_manager.start_all_schedulers(globals.client)
return {"status": "ok", "message": f"Server {data.guild_name} added successfully"}
else:
return {"status": "error", "message": "Failed to add server"}
return JSONResponse(status_code=500, content={"status": "error", "message": "Failed to add server"})
@router.delete("/servers/{guild_id}")
@@ -73,7 +74,7 @@ def remove_server(guild_id: int):
if success:
return {"status": "ok", "message": "Server removed successfully"}
else:
return {"status": "error", "message": "Failed to remove server"}
return JSONResponse(status_code=404, content={"status": "error", "message": "Failed to remove server"})
@router.put("/servers/{guild_id}")
@@ -85,7 +86,7 @@ def update_server(guild_id: int, data: dict):
server_manager.start_all_schedulers(globals.client)
return {"status": "ok", "message": "Server configuration updated"}
else:
return {"status": "error", "message": "Failed to update server configuration"}
return JSONResponse(status_code=500, content={"status": "error", "message": "Failed to update server configuration"})
@router.post("/servers/{guild_id}/bedtime-range")
@@ -96,7 +97,7 @@ def update_server_bedtime_range(guild_id: int, data: dict):
required_fields = ['bedtime_hour', 'bedtime_minute', 'bedtime_hour_end', 'bedtime_minute_end']
for field in required_fields:
if field not in data:
return {"status": "error", "message": f"Missing required field: {field}"}
return JSONResponse(status_code=400, content={"status": "error", "message": f"Missing required field: {field}"})
try:
bedtime_hour = int(data['bedtime_hour'])
@@ -105,12 +106,12 @@ def update_server_bedtime_range(guild_id: int, data: dict):
bedtime_minute_end = int(data['bedtime_minute_end'])
if not (0 <= bedtime_hour <= 23) or not (0 <= bedtime_hour_end <= 23):
return {"status": "error", "message": "Hours must be between 0 and 23"}
return JSONResponse(status_code=400, content={"status": "error", "message": "Hours must be between 0 and 23"})
if not (0 <= bedtime_minute <= 59) or not (0 <= bedtime_minute_end <= 59):
return {"status": "error", "message": "Minutes must be between 0 and 59"}
return JSONResponse(status_code=400, content={"status": "error", "message": "Minutes must be between 0 and 59"})
except (ValueError, TypeError):
return {"status": "error", "message": "Invalid time values provided"}
return JSONResponse(status_code=400, content={"status": "error", "message": "Invalid time values provided"})
success = server_manager.update_server_config(guild_id, **data)
if success:
@@ -122,9 +123,9 @@ def update_server_bedtime_range(guild_id: int, data: dict):
"message": f"Bedtime range updated: {bedtime_hour:02d}:{bedtime_minute:02d} - {bedtime_hour_end:02d}:{bedtime_minute_end:02d}"
}
else:
return {"status": "error", "message": "Updated config but failed to update scheduler"}
return JSONResponse(status_code=500, content={"status": "error", "message": "Updated config but failed to update scheduler"})
else:
return {"status": "error", "message": "Failed to update bedtime range"}
return JSONResponse(status_code=500, content={"status": "error", "message": "Failed to update bedtime range"})
@router.post("/servers/repair")
@@ -134,4 +135,4 @@ def repair_server_config():
server_manager.repair_config()
return {"status": "ok", "message": "Server configuration repaired and saved"}
except Exception as e:
return {"status": "error", "message": f"Failed to repair configuration: {e}"}
return JSONResponse(status_code=500, content={"status": "error", "message": f"Failed to repair configuration: {e}"})