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 @@
|
||||
"""Logging configuration routes: get/set log levels, filters, components."""
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import JSONResponse
|
||||
from routes.models import LogConfigUpdateRequest, LogFilterUpdateRequest
|
||||
from utils.logger import get_logger, list_components, get_component_stats
|
||||
from utils.log_config import (
|
||||
@@ -23,7 +24,7 @@ async def get_log_config():
|
||||
return {"success": True, "config": config}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get log config: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
|
||||
@router.post("/api/log/config")
|
||||
@@ -37,13 +38,13 @@ async def update_log_config(request: LogConfigUpdateRequest):
|
||||
enabled_levels=request.enabled_levels
|
||||
)
|
||||
if not success:
|
||||
return {"success": False, "error": f"Failed to update component {request.component}"}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": f"Failed to update component {request.component}"})
|
||||
|
||||
logger.info(f"Log config updated: component={request.component}, enabled_levels={request.enabled_levels}, enabled={request.enabled}")
|
||||
return {"success": True, "message": "Configuration updated"}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update log config: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
|
||||
@router.get("/api/log/components")
|
||||
@@ -60,7 +61,7 @@ async def get_log_components():
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get log components: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
|
||||
@router.post("/api/log/reload")
|
||||
@@ -72,10 +73,10 @@ async def reload_log_config():
|
||||
logger.info("Log configuration reloaded")
|
||||
return {"success": True, "message": "Configuration reloaded"}
|
||||
else:
|
||||
return {"success": False, "error": "Failed to reload configuration"}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": "Failed to reload configuration"})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to reload log config: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
|
||||
@router.post("/api/log/filters")
|
||||
@@ -93,10 +94,10 @@ async def update_log_filters(request: LogFilterUpdateRequest):
|
||||
logger.info(f"API filters updated: {request.dict(exclude_none=True)}")
|
||||
return {"success": True, "message": "Filters updated"}
|
||||
else:
|
||||
return {"success": False, "error": "Failed to update filters"}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": "Failed to update filters"})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update filters: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
|
||||
@router.post("/api/log/reset")
|
||||
@@ -108,10 +109,10 @@ async def reset_log_config():
|
||||
logger.info("Log configuration reset to defaults")
|
||||
return {"success": True, "message": "Configuration reset to defaults"}
|
||||
else:
|
||||
return {"success": False, "error": "Failed to reset configuration"}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": "Failed to reset configuration"})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to reset log config: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
|
||||
@router.post("/api/log/global-level")
|
||||
@@ -125,10 +126,10 @@ async def update_global_level_endpoint(level: str, enabled: bool):
|
||||
logger.info(f"Global level {level} {action} across all components")
|
||||
return {"success": True, "message": f"Level {level} {action} globally"}
|
||||
else:
|
||||
return {"success": False, "error": f"Failed to update global level {level}"}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": f"Failed to update global level {level}"})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update global level: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
|
||||
@router.post("/api/log/timestamp-format")
|
||||
@@ -140,10 +141,10 @@ async def update_timestamp_format_endpoint(format_type: str):
|
||||
logger.info(f"Timestamp format updated to: {format_type}")
|
||||
return {"success": True, "message": f"Timestamp format set to: {format_type}"}
|
||||
else:
|
||||
return {"success": False, "error": f"Invalid timestamp format: {format_type}"}
|
||||
return JSONResponse(status_code=400, content={"success": False, "error": f"Invalid timestamp format: {format_type}"})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update timestamp format: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
|
||||
@router.get("/api/log/files/{component}")
|
||||
@@ -155,7 +156,7 @@ async def get_log_file(component: str, lines: int = 100):
|
||||
log_file = log_dir / f'{component.replace(".", "_")}.log'
|
||||
|
||||
if not log_file.exists():
|
||||
return {"success": False, "error": "Log file not found"}
|
||||
return JSONResponse(status_code=404, content={"success": False, "error": "Log file not found"})
|
||||
|
||||
with open(log_file, 'r', encoding='utf-8') as f:
|
||||
all_lines = f.readlines()
|
||||
@@ -170,4 +171,4 @@ async def get_log_file(component: str, lines: int = 100):
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to read log file for {component}: {e}")
|
||||
return {"success": False, "error": str(e)}
|
||||
return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
|
||||
|
||||
Reference in New Issue
Block a user