arkan-api / app /core /exceptions.py
masry86's picture
initial commit - arkan backend
de0f1ef
#\\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,
},
)