Wire production domain, CORS for tenant subdomains, celery volume mounts, and nginx reverse proxy configs for apex, API, identity, auth, and wildcard tenants. Co-authored-by: Cursor <cursoragent@cursor.com>
80 lines
2.2 KiB
Python
80 lines
2.2 KiB
Python
"""استثناهای مشترک دامنه (Domain Exceptions).
|
|
|
|
این استثناها مستقل از فریمورک هستند تا در همه سرویسها قابل استفاده باشند.
|
|
لایه API هر سرویس آنها را به پاسخ HTTP مناسب تبدیل میکند.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
|
|
class AppError(Exception):
|
|
"""پایه همه خطاهای دامنهای برنامه."""
|
|
|
|
status_code: int = 500
|
|
error_code: str = "internal_error"
|
|
|
|
def __init__(
|
|
self,
|
|
message: str | None = None,
|
|
*,
|
|
error_code: str | None = None,
|
|
status_code: int | None = None,
|
|
details: Any | None = None,
|
|
) -> None:
|
|
self.message = message or self.__class__.__doc__ or "Application error"
|
|
if error_code is not None:
|
|
self.error_code = error_code
|
|
if status_code is not None:
|
|
self.status_code = status_code
|
|
self.details = details
|
|
super().__init__(self.message)
|
|
|
|
|
|
class NotFoundError(AppError):
|
|
"""منبع درخواستی یافت نشد."""
|
|
|
|
status_code = 404
|
|
error_code = "not_found"
|
|
|
|
|
|
class ConflictError(AppError):
|
|
"""تعارض داده (مثلاً مقدار تکراری)."""
|
|
|
|
status_code = 409
|
|
error_code = "conflict"
|
|
|
|
|
|
class ValidationAppError(AppError):
|
|
"""داده ورودی نامعتبر است."""
|
|
|
|
status_code = 422
|
|
error_code = "validation_error"
|
|
|
|
|
|
class UnauthorizedError(AppError):
|
|
"""احراز هویت انجام نشده است."""
|
|
|
|
status_code = 401
|
|
error_code = "unauthorized"
|
|
|
|
|
|
class ForbiddenError(AppError):
|
|
"""دسترسی مجاز نیست."""
|
|
|
|
status_code = 403
|
|
error_code = "forbidden"
|
|
|
|
|
|
class TenantNotResolvedError(AppError):
|
|
"""tenant قابل تشخیص نبود در حالی که endpoint نیازمند tenant است."""
|
|
|
|
status_code = 400
|
|
error_code = "tenant_not_resolved"
|
|
|
|
|
|
class FeatureAccessDeniedError(ForbiddenError):
|
|
"""tenant به این قابلیت دسترسی ندارد."""
|
|
|
|
error_code = "feature_access_denied"
|