#\\wsl$\Ubuntu\home\masry\arkan-new\backend\app\core\exceptions.py from fastapi import HTTPException, Request, status from fastapi.responses import JSONResponse class AppException(HTTPException): """Base exception — كل الاستثناءات ترث منها.""" def __init__(self, status_code: int, detail: str, code: str = "ERROR"): super().__init__(status_code=status_code, detail=detail) self.code = code class NotFoundError(AppException): def __init__(self, resource: str = "Resource"): super().__init__(404, f"{resource} not found", "NOT_FOUND") class ConflictError(AppException): def __init__(self, detail: str = "Resource already exists"): super().__init__(409, detail, "CONFLICT") class ForbiddenError(AppException): def __init__(self, detail: str = "Permission denied"): super().__init__(403, detail, "FORBIDDEN") class UnauthorizedError(AppException): def __init__(self, detail: str = "Authentication required"): super().__init__( 401, detail, "UNAUTHORIZED", # headers سيُضاف تلقائيًا في المعالج ) self.headers = {"WWW-Authenticate": "Bearer"} # ─── Global handlers ────────────────────────────────────────────────────────── async def app_exception_handler(request: Request, exc: AppException) -> JSONResponse: return JSONResponse( status_code=exc.status_code, content={ "error": exc.code, "detail": exc.detail, "path": request.url.path, }, headers=getattr(exc, "headers", None), ) async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse: return JSONResponse( status_code=500, content={ "error": "INTERNAL_ERROR", "detail": "An unexpected error occurred.", "path": request.url.path, }, )