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:
@@ -1,6 +1,7 @@
|
||||
"""Autonomous action routes: V1, V2, per-server autonomous."""
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import JSONResponse
|
||||
import globals
|
||||
from server_manager import server_manager
|
||||
from routes.models import CustomPromptRequest
|
||||
@@ -25,7 +26,7 @@ async def trigger_autonomous_general(guild_id: int = None):
|
||||
globals.client.loop.create_task(miku_say_something_general())
|
||||
return {"status": "ok", "message": "Autonomous general message queued for all servers"}
|
||||
else:
|
||||
return {"status": "error", "message": "Bot not ready"}
|
||||
return JSONResponse(status_code=503, content={"status": "error", "message": "Bot not ready"})
|
||||
|
||||
|
||||
@router.post("/autonomous/engage")
|
||||
@@ -65,7 +66,7 @@ async def trigger_autonomous_engage_user(
|
||||
|
||||
return {"status": "ok", "message": " ".join(msg_parts)}
|
||||
else:
|
||||
return {"status": "error", "message": "Bot not ready"}
|
||||
return JSONResponse(status_code=503, content={"status": "error", "message": "Bot not ready"})
|
||||
|
||||
|
||||
@router.post("/autonomous/tweet")
|
||||
@@ -86,7 +87,7 @@ async def trigger_autonomous_tweet(guild_id: int = None, tweet_url: str = None):
|
||||
msg += f" with URL {tweet_url}"
|
||||
return {"status": "ok", "message": msg}
|
||||
else:
|
||||
return {"status": "error", "message": "Bot not ready"}
|
||||
return JSONResponse(status_code=503, content={"status": "error", "message": "Bot not ready"})
|
||||
|
||||
|
||||
@router.post("/autonomous/custom")
|
||||
@@ -101,7 +102,7 @@ async def custom_autonomous_message(req: CustomPromptRequest, guild_id: int = No
|
||||
globals.client.loop.create_task(handle_custom_prompt(req.prompt))
|
||||
return {"status": "ok", "message": "Custom autonomous message queued for all servers"}
|
||||
else:
|
||||
return {"status": "error", "message": "Bot not ready"}
|
||||
return JSONResponse(status_code=503, content={"status": "error", "message": "Bot not ready"})
|
||||
|
||||
|
||||
@router.post("/autonomous/reaction")
|
||||
@@ -116,7 +117,7 @@ async def trigger_autonomous_reaction(guild_id: int = None):
|
||||
globals.client.loop.create_task(miku_autonomous_reaction(force=True))
|
||||
return {"status": "ok", "message": "Autonomous reaction queued for all servers"}
|
||||
else:
|
||||
return {"status": "error", "message": "Bot not ready"}
|
||||
return JSONResponse(status_code=503, content={"status": "error", "message": "Bot not ready"})
|
||||
|
||||
|
||||
@router.post("/autonomous/join-conversation")
|
||||
@@ -135,7 +136,7 @@ async def trigger_detect_and_join_conversation(guild_id: int = None):
|
||||
return {"status": "ok", "message": "Detect and join conversation queued for all servers"}
|
||||
else:
|
||||
logger.error(f"Bot not ready: client={globals.client}, loop={globals.client.loop if globals.client else None}")
|
||||
return {"status": "error", "message": "Bot not ready"}
|
||||
return JSONResponse(status_code=503, content={"status": "error", "message": "Bot not ready"})
|
||||
|
||||
|
||||
# ========== Per-Server Autonomous ==========
|
||||
@@ -148,7 +149,7 @@ async def trigger_autonomous_general_for_server(guild_id: int):
|
||||
await miku_say_something_general_for_server(guild_id)
|
||||
return {"status": "ok", "message": f"Autonomous general message triggered for server {guild_id}"}
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": f"Failed to trigger autonomous message: {e}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Failed to trigger autonomous message: {e}"})
|
||||
|
||||
|
||||
@router.post("/servers/{guild_id}/autonomous/engage")
|
||||
@@ -175,7 +176,7 @@ async def trigger_autonomous_engage_for_server(
|
||||
|
||||
return {"status": "ok", "message": " ".join(msg_parts)}
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": f"Failed to trigger user engagement: {e}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Failed to trigger user engagement: {e}"})
|
||||
|
||||
|
||||
@router.post("/servers/{guild_id}/autonomous/custom")
|
||||
@@ -187,9 +188,9 @@ async def custom_autonomous_message_for_server(guild_id: int, req: CustomPromptR
|
||||
if success:
|
||||
return {"status": "ok", "message": f"Custom autonomous message sent to server {guild_id}"}
|
||||
else:
|
||||
return {"status": "error", "message": f"Failed to send custom message to server {guild_id}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Failed to send custom message to server {guild_id}"})
|
||||
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("/servers/{guild_id}/autonomous/tweet")
|
||||
@@ -200,7 +201,7 @@ async def trigger_autonomous_tweet_for_server(guild_id: int):
|
||||
await share_miku_tweet_for_server(guild_id)
|
||||
return {"status": "ok", "message": f"Autonomous tweet sharing triggered for server {guild_id}"}
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": f"Failed to trigger tweet sharing: {e}"}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": f"Failed to trigger tweet sharing: {e}"})
|
||||
|
||||
|
||||
# ========== Autonomous V2 ==========
|
||||
@@ -213,7 +214,7 @@ async def get_v2_stats(guild_id: int):
|
||||
stats = get_v2_stats_for_server(guild_id)
|
||||
return {"status": "ok", "guild_id": guild_id, "stats": stats}
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": str(e)}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": str(e)})
|
||||
|
||||
|
||||
@router.get("/autonomous/v2/check/{guild_id}")
|
||||
@@ -223,16 +224,16 @@ async def manual_v2_check(guild_id: int):
|
||||
from utils.autonomous_v2_integration import manual_trigger_v2_check
|
||||
|
||||
if not globals.client:
|
||||
return {"status": "error", "message": "Bot not ready"}
|
||||
return JSONResponse(status_code=503, content={"status": "error", "message": "Bot not ready"})
|
||||
|
||||
result = await manual_trigger_v2_check(guild_id, globals.client)
|
||||
|
||||
if isinstance(result, str):
|
||||
return {"status": "error", "message": result}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": result})
|
||||
|
||||
return {"status": "ok", "guild_id": guild_id, "analysis": result}
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": str(e)}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": str(e)})
|
||||
|
||||
|
||||
@router.get("/autonomous/v2/status")
|
||||
@@ -258,4 +259,4 @@ async def get_v2_status():
|
||||
|
||||
return {"status": "ok", "servers": status}
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": str(e)}
|
||||
return JSONResponse(status_code=500, content={"status": "error", "message": str(e)})
|
||||
|
||||
Reference in New Issue
Block a user