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:
@@ -3,6 +3,7 @@
|
||||
import io
|
||||
from typing import List
|
||||
from fastapi import APIRouter, UploadFile, File, Form
|
||||
from fastapi.responses import JSONResponse
|
||||
import discord
|
||||
import globals
|
||||
from utils.logger import get_logger
|
||||
@@ -23,7 +24,7 @@ async def manual_send(
|
||||
try:
|
||||
channel = globals.client.get_channel(int(channel_id))
|
||||
if not channel:
|
||||
return {"status": "error", "message": "Channel not found"}
|
||||
return JSONResponse(status_code=404, content={"status": "error", "message": "Channel not found"})
|
||||
|
||||
# Read file content immediately before the request closes
|
||||
file_data = []
|
||||
@@ -36,7 +37,7 @@ async def manual_send(
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to read file {file.filename}: {e}")
|
||||
return {"status": "error", "message": f"Failed to read file {file.filename}: {e}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Failed to read file {file.filename}: {e}"})
|
||||
|
||||
async def send_message_and_files():
|
||||
try:
|
||||
@@ -70,7 +71,7 @@ async def manual_send(
|
||||
return {"status": "ok", "message": "Message and files queued for sending"}
|
||||
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": f"Error: {e}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Error: {e}"})
|
||||
|
||||
|
||||
@router.post("/manual/send-webhook")
|
||||
@@ -88,10 +89,10 @@ async def manual_send_webhook(
|
||||
|
||||
channel = globals.client.get_channel(int(channel_id))
|
||||
if not channel:
|
||||
return {"status": "error", "message": "Channel not found"}
|
||||
return JSONResponse(status_code=404, content={"status": "error", "message": "Channel not found"})
|
||||
|
||||
if persona not in ["miku", "evil"]:
|
||||
return {"status": "error", "message": "Invalid persona. Must be 'miku' or 'evil'"}
|
||||
return JSONResponse(status_code=400, content={"status": "error", "message": "Invalid persona. Must be 'miku' or 'evil'"})
|
||||
|
||||
file_data = []
|
||||
for file in files:
|
||||
@@ -103,7 +104,7 @@ async def manual_send_webhook(
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to read file {file.filename}: {e}")
|
||||
return {"status": "error", "message": f"Failed to read file {file.filename}: {e}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Failed to read file {file.filename}: {e}"})
|
||||
|
||||
async def send_webhook_message():
|
||||
try:
|
||||
@@ -146,7 +147,7 @@ async def manual_send_webhook(
|
||||
return {"status": "ok", "message": f"Webhook message queued for sending as {persona}"}
|
||||
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": f"Error: {e}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Error: {e}"})
|
||||
|
||||
|
||||
@router.post("/messages/react")
|
||||
@@ -158,17 +159,17 @@ async def add_reaction_to_message(
|
||||
"""Add a reaction to a specific message"""
|
||||
try:
|
||||
if not globals.client or not globals.client.loop or not globals.client.loop.is_running():
|
||||
return {"status": "error", "message": "Bot not ready"}
|
||||
return JSONResponse(status_code=503, content={"status": "error", "message": "Bot not ready"})
|
||||
|
||||
try:
|
||||
msg_id = int(message_id)
|
||||
chan_id = int(channel_id)
|
||||
except ValueError:
|
||||
return {"status": "error", "message": "Invalid message ID or channel ID format"}
|
||||
return JSONResponse(status_code=400, content={"status": "error", "message": "Invalid message ID or channel ID format"})
|
||||
|
||||
channel = globals.client.get_channel(chan_id)
|
||||
if not channel:
|
||||
return {"status": "error", "message": f"Channel {channel_id} not found"}
|
||||
return JSONResponse(status_code=404, content={"status": "error", "message": f"Channel {channel_id} not found"})
|
||||
|
||||
async def add_reaction_task():
|
||||
try:
|
||||
@@ -193,4 +194,4 @@ async def add_reaction_to_message(
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to add reaction: {e}")
|
||||
return {"status": "error", "message": f"Failed to add reaction: {e}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Failed to add reaction: {e}"})
|
||||
|
||||
Reference in New Issue
Block a user