feat: add new custom 500 exceptions
This commit is contained in:
@@ -8,3 +8,6 @@ from src.application.domain.exceptions.internal_exception import InternalExcepti
|
|||||||
from src.application.domain.exceptions.service_unavailable_exception import ServiceUnavailableException
|
from src.application.domain.exceptions.service_unavailable_exception import ServiceUnavailableException
|
||||||
from src.application.domain.exceptions.too_many_requests_exception import TooManyRequestsException
|
from src.application.domain.exceptions.too_many_requests_exception import TooManyRequestsException
|
||||||
from src.application.domain.exceptions.csrf_error_exception import CsrfErrorException
|
from src.application.domain.exceptions.csrf_error_exception import CsrfErrorException
|
||||||
|
from src.application.domain.exceptions.jwt_error_exception import JwtErrorException
|
||||||
|
from src.application.domain.exceptions.data_base_error_exception import DataBaseErrorException
|
||||||
|
from src.application.domain.exceptions.rate_limit_error_exception import RateLimitErrorException
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
from src.application.domain.exceptions.application_exceptions import ApplicationException
|
||||||
|
|
||||||
|
from typing import Mapping
|
||||||
|
|
||||||
|
|
||||||
|
class DataBaseErrorException(ApplicationException):
|
||||||
|
def __init__(self, message: str = 'Database error occurred', headers: Mapping[str, str] | None = None):
|
||||||
|
super().__init__(500, message, headers)
|
||||||
8
src/application/domain/exceptions/jwt_error_exception.py
Normal file
8
src/application/domain/exceptions/jwt_error_exception.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from src.application.domain.exceptions.application_exceptions import ApplicationException
|
||||||
|
|
||||||
|
from typing import Mapping
|
||||||
|
|
||||||
|
|
||||||
|
class JwtErrorException(ApplicationException):
|
||||||
|
def __init__(self, message: str = 'JWT error occurred', headers: Mapping[str, str] | None = None):
|
||||||
|
super().__init__(500, message, headers)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
from src.application.domain.exceptions.application_exceptions import ApplicationException
|
||||||
|
|
||||||
|
from typing import Mapping
|
||||||
|
|
||||||
|
|
||||||
|
class RateLimitErrorException(ApplicationException):
|
||||||
|
def __init__(self, message: str = 'Rate limit error occurred', headers: Mapping[str, str] | None = None):
|
||||||
|
super().__init__(500, message, headers)
|
||||||
@@ -3,7 +3,7 @@ from sqlalchemy import select
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
from src.application.domain.exceptions import ApplicationException, BadRequestException, InternalException, NotFoundException
|
from src.application.domain.exceptions import ApplicationException, BadRequestException, DataBaseErrorException, NotFoundException
|
||||||
from src.application.abstractions.repositories import IUserRepository
|
from src.application.abstractions.repositories import IUserRepository
|
||||||
from src.application.domain.entities import UserEntity
|
from src.application.domain.entities import UserEntity
|
||||||
from src.infrastructure.database.models import UserModel
|
from src.infrastructure.database.models import UserModel
|
||||||
@@ -60,7 +60,7 @@ class UserRepository(IUserRepository):
|
|||||||
raise
|
raise
|
||||||
except SQLAlchemyError as exception:
|
except SQLAlchemyError as exception:
|
||||||
self._logger.exception(str(exception))
|
self._logger.exception(str(exception))
|
||||||
raise InternalException(message=f'Database error: {str(exception)}')
|
raise DataBaseErrorException(message=f'Database error: {str(exception)}')
|
||||||
|
|
||||||
async def _update_field(self, user_id: str, **fields: object) -> UserEntity:
|
async def _update_field(self, user_id: str, **fields: object) -> UserEntity:
|
||||||
try:
|
try:
|
||||||
@@ -74,7 +74,7 @@ class UserRepository(IUserRepository):
|
|||||||
raise
|
raise
|
||||||
except SQLAlchemyError as exception:
|
except SQLAlchemyError as exception:
|
||||||
self._logger.exception(str(exception))
|
self._logger.exception(str(exception))
|
||||||
raise InternalException(message=f'Database error: {str(exception)}')
|
raise DataBaseErrorException(message=f'Database error: {str(exception)}')
|
||||||
|
|
||||||
async def set_phone(self, user_id: str, phone: str) -> UserEntity:
|
async def set_phone(self, user_id: str, phone: str) -> UserEntity:
|
||||||
return await self._update_field(user_id, phone=phone)
|
return await self._update_field(user_id, phone=phone)
|
||||||
@@ -100,7 +100,7 @@ class UserRepository(IUserRepository):
|
|||||||
raise
|
raise
|
||||||
except SQLAlchemyError as exception:
|
except SQLAlchemyError as exception:
|
||||||
self._logger.exception(str(exception))
|
self._logger.exception(str(exception))
|
||||||
raise InternalException(message=f'Database error: {str(exception)}')
|
raise DataBaseErrorException(message=f'Database error: {str(exception)}')
|
||||||
|
|
||||||
async def set_password(self, user_id: str, password_hash: str) -> UserEntity:
|
async def set_password(self, user_id: str, password_hash: str) -> UserEntity:
|
||||||
return await self._update_field(user_id, password_hash=password_hash)
|
return await self._update_field(user_id, password_hash=password_hash)
|
||||||
@@ -121,7 +121,7 @@ class UserRepository(IUserRepository):
|
|||||||
return result.scalar_one_or_none() is not None
|
return result.scalar_one_or_none() is not None
|
||||||
except SQLAlchemyError as exception:
|
except SQLAlchemyError as exception:
|
||||||
self._logger.exception(str(exception))
|
self._logger.exception(str(exception))
|
||||||
raise InternalException(message=f'Database error: {str(exception)}')
|
raise DataBaseErrorException(message=f'Database error: {str(exception)}')
|
||||||
|
|
||||||
async def get_user_by_email(self, email: str) -> UserEntity | None:
|
async def get_user_by_email(self, email: str) -> UserEntity | None:
|
||||||
try:
|
try:
|
||||||
@@ -139,4 +139,4 @@ class UserRepository(IUserRepository):
|
|||||||
return self._to_entity(user)
|
return self._to_entity(user)
|
||||||
except SQLAlchemyError as exception:
|
except SQLAlchemyError as exception:
|
||||||
self._logger.exception(str(exception))
|
self._logger.exception(str(exception))
|
||||||
raise InternalException(message=f'Database error: {str(exception)}')
|
raise DataBaseErrorException(message=f'Database error: {str(exception)}')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
from jose import jwt, ExpiredSignatureError, JWTError
|
from jose import jwt, ExpiredSignatureError, JWTError
|
||||||
from src.application.contracts import ILogger, IJwtService
|
from src.application.contracts import ILogger, IJwtService
|
||||||
from src.application.domain.dto import AccessTokenPayload
|
from src.application.domain.dto import AccessTokenPayload
|
||||||
from src.application.domain.exceptions import ApplicationException, UnauthorizedException, InternalException
|
from src.application.domain.exceptions import ApplicationException, UnauthorizedException, JwtErrorException
|
||||||
from src.infrastructure.config.settings import settings
|
from src.infrastructure.config.settings import settings
|
||||||
from src.infrastructure.vault import JwtKeyStore
|
from src.infrastructure.vault import JwtKeyStore
|
||||||
|
|
||||||
@@ -106,4 +106,4 @@ class JwtService(IJwtService):
|
|||||||
|
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
self._logger.error(f'Unexpected JWT decode error kid={kid} error={str(exception)}')
|
self._logger.error(f'Unexpected JWT decode error kid={kid} error={str(exception)}')
|
||||||
raise InternalException(message='JWT decode failed')
|
raise JwtErrorException(message='JWT decode failed')
|
||||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from src.application.domain.dto import JwtPublicKeySet, JwtPublicKey
|
from src.application.domain.dto import JwtPublicKeySet, JwtPublicKey
|
||||||
from src.application.domain.exceptions import InternalException
|
from src.application.domain.exceptions import JwtErrorException
|
||||||
from src.infrastructure.vault.client import VaultClient
|
from src.infrastructure.vault.client import VaultClient
|
||||||
|
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ class JwtKeyStore:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_instance(cls) -> 'JwtKeyStore':
|
def get_instance(cls) -> 'JwtKeyStore':
|
||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
raise InternalException(message='JwtKeyStore not initialized')
|
raise JwtErrorException(message='JwtKeyStore not initialized')
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
def _read_keyset_sync(self) -> JwtPublicKeySet:
|
def _read_keyset_sync(self) -> JwtPublicKeySet:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from fastapi import Request
|
|||||||
from redis.asyncio.client import Redis
|
from redis.asyncio.client import Redis
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
from src.application.domain.exceptions import (
|
from src.application.domain.exceptions import (
|
||||||
InternalException,
|
RateLimitErrorException,
|
||||||
ServiceUnavailableException,
|
ServiceUnavailableException,
|
||||||
TooManyRequestsException,
|
TooManyRequestsException,
|
||||||
)
|
)
|
||||||
@@ -128,7 +128,7 @@ def rate_limit(
|
|||||||
ident = _call_key_builder(key_builder, request, args, kwargs) # type: ignore[arg-type]
|
ident = _call_key_builder(key_builder, request, args, kwargs) # type: ignore[arg-type]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f'RateLimit key_builder failed error={str(e)}')
|
logger.error(f'RateLimit key_builder failed error={str(e)}')
|
||||||
raise InternalException(message='Rate limiter key_builder failed')
|
raise RateLimitErrorException(message='Rate limiter key_builder failed')
|
||||||
|
|
||||||
route = request.url.path
|
route = request.url.path
|
||||||
method = request.method
|
method = request.method
|
||||||
|
|||||||
Reference in New Issue
Block a user