error response due to language models are updated
This commit is contained in:
parent
ad0b9aa218
commit
25539c56cc
|
|
@ -17,21 +17,11 @@ from prometheus_fastapi_instrumentator import Instrumentator
|
||||||
from app_handler import setup_middleware, get_uvicorn_config
|
from app_handler import setup_middleware, get_uvicorn_config
|
||||||
|
|
||||||
|
|
||||||
print("Loading app.py module...")
|
app = create_app(routers=routers) # Initialize FastAPI application
|
||||||
|
Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics
|
||||||
# Initialize FastAPI application
|
setup_middleware(app) # Configure middleware and exception handlers
|
||||||
app = create_app(routers=routers)
|
|
||||||
|
|
||||||
# Setup Prometheus metrics
|
|
||||||
Instrumentator().instrument(app=app).expose(app=app)
|
|
||||||
|
|
||||||
# Configure middleware and exception handlers
|
|
||||||
setup_middleware(app)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print("Starting server from __main__...")
|
uvicorn_config = get_uvicorn_config() # Run the application with Uvicorn
|
||||||
# Run the application with Uvicorn
|
|
||||||
uvicorn_config = get_uvicorn_config()
|
|
||||||
print(f"Using config: {uvicorn_config}")
|
|
||||||
uvicorn.Server(uvicorn.Config(**uvicorn_config)).run()
|
uvicorn.Server(uvicorn.Config(**uvicorn_config)).run()
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,8 @@ from typing import Dict, Any
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi import FastAPI, Request, HTTPException, status
|
from fastapi import FastAPI, Request, HTTPException, status
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
|
from ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||||
from ErrorHandlers.bases import (
|
from middleware.auth_middleware import RequestTimingMiddleware
|
||||||
BaseErrorModelClass,
|
|
||||||
StatusesModelClass,
|
|
||||||
LanguageModelClass,
|
|
||||||
)
|
|
||||||
from ErrorHandlers import statuses
|
|
||||||
from middleware.auth_middleware import MiddlewareModule
|
|
||||||
|
|
||||||
|
|
||||||
def setup_cors_middleware(app: FastAPI) -> None:
|
def setup_cors_middleware(app: FastAPI) -> None:
|
||||||
|
|
@ -38,33 +32,6 @@ def setup_cors_middleware(app: FastAPI) -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
|
|
||||||
"""
|
|
||||||
Handle HTTP exceptions and return formatted error responses.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: FastAPI request object
|
|
||||||
exc: HTTP exception instance
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
JSONResponse: Formatted error response
|
|
||||||
"""
|
|
||||||
error_code = getattr(exc, "error_code", None)
|
|
||||||
if error_code:
|
|
||||||
status_code = StatusesModelClass.retrieve_error_by_code(error_code)
|
|
||||||
error_message = LanguageModelClass.retrieve_error_by_code(
|
|
||||||
error_code, request.headers.get("accept-language", "en")
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
status_code = exc.status_code
|
|
||||||
error_message = str(exc.detail)
|
|
||||||
|
|
||||||
return JSONResponse(
|
|
||||||
status_code=status_code,
|
|
||||||
content={"detail": error_message, "error_code": error_code},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
|
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
|
||||||
"""
|
"""
|
||||||
Handle generic exceptions and return formatted error responses.
|
Handle generic exceptions and return formatted error responses.
|
||||||
|
|
@ -89,7 +56,12 @@ def setup_exception_handlers(app: FastAPI) -> None:
|
||||||
Args:
|
Args:
|
||||||
app: FastAPI application instance
|
app: FastAPI application instance
|
||||||
"""
|
"""
|
||||||
app.add_exception_handler(HTTPException, http_exception_handler)
|
from ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
|
||||||
|
|
||||||
|
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
|
||||||
|
app.add_exception_handler(
|
||||||
|
HTTPExceptionApi, custom_exception_handler.handle_exception
|
||||||
|
)
|
||||||
app.add_exception_handler(Exception, generic_exception_handler)
|
app.add_exception_handler(Exception, generic_exception_handler)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -101,7 +73,7 @@ def setup_middleware(app: FastAPI) -> None:
|
||||||
app: FastAPI application instance
|
app: FastAPI application instance
|
||||||
"""
|
"""
|
||||||
setup_cors_middleware(app)
|
setup_cors_middleware(app)
|
||||||
app.add_middleware(MiddlewareModule.RequestTimingMiddleware)
|
app.add_middleware(RequestTimingMiddleware)
|
||||||
setup_exception_handlers(app)
|
setup_exception_handlers(app)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ This module provides functionality to create and configure a FastAPI application
|
||||||
- Response class configuration
|
- Response class configuration
|
||||||
- Security requirements for protected endpoints
|
- Security requirements for protected endpoints
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Optional, Union
|
||||||
from fastapi import FastAPI, APIRouter
|
from fastapi import FastAPI, APIRouter
|
||||||
|
|
@ -36,10 +37,7 @@ def setup_security_schema() -> Dict[str, Any]:
|
||||||
|
|
||||||
|
|
||||||
def configure_route_security(
|
def configure_route_security(
|
||||||
path: str,
|
path: str, method: str, schema: Dict[str, Any], protected_paths: List[str]
|
||||||
method: str,
|
|
||||||
schema: Dict[str, Any],
|
|
||||||
protected_paths: List[str]
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Configure security requirements for a specific route.
|
Configure security requirements for a specific route.
|
||||||
|
|
@ -113,7 +111,7 @@ def create_app(routers: ModuleType) -> FastAPI:
|
||||||
for route in router.routes:
|
for route in router.routes:
|
||||||
if isinstance(route, APIRoute):
|
if isinstance(route, APIRoute):
|
||||||
# Check if the route has auth_required decorator
|
# Check if the route has auth_required decorator
|
||||||
if any(d.__name__ == 'auth_required' for d in route.dependencies):
|
if any(d.__name__ == "auth_required" for d in route.dependencies):
|
||||||
protected_paths.append(route.path)
|
protected_paths.append(route.path)
|
||||||
|
|
||||||
# Include routers
|
# Include routers
|
||||||
|
|
@ -142,7 +140,7 @@ def create_app(routers: ModuleType) -> FastAPI:
|
||||||
route.path,
|
route.path,
|
||||||
route.methods.pop().lower(),
|
route.methods.pop().lower(),
|
||||||
openapi_schema,
|
openapi_schema,
|
||||||
protected_paths
|
protected_paths,
|
||||||
)
|
)
|
||||||
|
|
||||||
app.openapi_schema = openapi_schema
|
app.openapi_schema = openapi_schema
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ and a middleware for request timing measurements.
|
||||||
from time import perf_counter
|
from time import perf_counter
|
||||||
from typing import Callable, Optional, Dict, Any, Tuple
|
from typing import Callable, Optional, Dict, Any, Tuple
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from fastapi import HTTPException, Request, Response, status
|
from fastapi import Request, Response
|
||||||
from starlette.middleware.base import BaseHTTPMiddleware
|
from starlette.middleware.base import BaseHTTPMiddleware
|
||||||
from AllConfigs.Token.config import Auth
|
from AllConfigs.Token.config import Auth
|
||||||
from ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApi
|
from ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApi
|
||||||
|
|
@ -21,7 +21,6 @@ class MiddlewareModule:
|
||||||
This class provides:
|
This class provides:
|
||||||
- Token extraction and validation
|
- Token extraction and validation
|
||||||
- Authentication decorator for endpoints
|
- Authentication decorator for endpoints
|
||||||
- Request timing middleware
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -40,23 +39,15 @@ class MiddlewareModule:
|
||||||
"""
|
"""
|
||||||
auth_header = request.headers.get(Auth.ACCESS_TOKEN_TAG)
|
auth_header = request.headers.get(Auth.ACCESS_TOKEN_TAG)
|
||||||
if not auth_header:
|
if not auth_header:
|
||||||
raise HTTPExceptionApi(
|
raise HTTPExceptionApi(error_code="HTTP_401_UNAUTHORIZED", lang="tr")
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
||||||
detail="No authorization header",
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
scheme, token = auth_header.split()
|
scheme, token = auth_header.split()
|
||||||
if scheme.lower() != "bearer":
|
if scheme.lower() != "bearer":
|
||||||
raise HTTPExceptionApi(
|
raise HTTPExceptionApi(error_code="HTTP_401_UNAUTHORIZED", lang="tr")
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
||||||
detail="Invalid authentication scheme",
|
|
||||||
)
|
|
||||||
return scheme, token
|
return scheme, token
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise HTTPExceptionApi(
|
raise HTTPExceptionApi(error_code="HTTP_401_UNAUTHORIZED", lang="tr")
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token format"
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def validate_token(token: str) -> Dict[str, Any]:
|
async def validate_token(token: str) -> Dict[str, Any]:
|
||||||
|
|
@ -78,10 +69,7 @@ class MiddlewareModule:
|
||||||
# return jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
|
# return jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
|
||||||
return {"user_id": "test", "role": "user"} # Placeholder
|
return {"user_id": "test", "role": "user"} # Placeholder
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPExceptionApi(
|
raise HTTPExceptionApi(error_code="HTTP_401_UNAUTHORIZED", lang="tr")
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
||||||
detail=f"Token validation failed: {str(e)}",
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def auth_required(cls, func: Callable) -> Callable:
|
def auth_required(cls, func: Callable) -> Callable:
|
||||||
|
|
@ -122,16 +110,13 @@ class MiddlewareModule:
|
||||||
return await func(request, *args, **kwargs)
|
return await func(request, *args, **kwargs)
|
||||||
|
|
||||||
except HTTPExceptionApi:
|
except HTTPExceptionApi:
|
||||||
raise
|
raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPExceptionApi(
|
raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr")
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
||||||
detail=f"Authentication failed: {str(e)}",
|
|
||||||
)
|
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
class RequestTimingMiddleware(BaseHTTPMiddleware):
|
|
||||||
|
class RequestTimingMiddleware(BaseHTTPMiddleware):
|
||||||
"""
|
"""
|
||||||
Middleware for measuring and logging request timing.
|
Middleware for measuring and logging request timing.
|
||||||
Only handles timing, no authentication.
|
Only handles timing, no authentication.
|
||||||
|
|
@ -154,19 +139,6 @@ class MiddlewareModule:
|
||||||
response = await call_next(request)
|
response = await call_next(request)
|
||||||
|
|
||||||
# Add timing information to response headers
|
# Add timing information to response headers
|
||||||
self._add_timing_headers(response, start_time)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _add_timing_headers(response: Response, start_time: float) -> None:
|
|
||||||
"""
|
|
||||||
Add request timing information to response headers.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
response: FastAPI response object
|
|
||||||
start_time: Time when request processing started
|
|
||||||
"""
|
|
||||||
end_time = perf_counter()
|
end_time = perf_counter()
|
||||||
elapsed = (end_time - start_time) * 1000 # Convert to milliseconds
|
elapsed = (end_time - start_time) * 1000 # Convert to milliseconds
|
||||||
|
|
||||||
|
|
@ -177,3 +149,5 @@ class MiddlewareModule:
|
||||||
"request-duration": f"{elapsed:.2f}ms",
|
"request-duration": f"{elapsed:.2f}ms",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,9 @@ class OpenAPISchemaCreator:
|
||||||
if "components" not in openapi_schema:
|
if "components" not in openapi_schema:
|
||||||
openapi_schema["components"] = {}
|
openapi_schema["components"] = {}
|
||||||
|
|
||||||
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
|
openapi_schema["components"][
|
||||||
|
"securitySchemes"
|
||||||
|
] = self._create_security_schemes()
|
||||||
|
|
||||||
# Configure route security and responses
|
# Configure route security and responses
|
||||||
for route in self.app.routes:
|
for route in self.app.routes:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
from .base_router import test_route
|
from .base_router import test_route
|
||||||
|
|
||||||
__all__ = [
|
__all__ = ["test_route"]
|
||||||
"test_route"
|
|
||||||
]
|
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,16 @@ from middleware.auth_middleware import MiddlewareModule
|
||||||
|
|
||||||
# Create test router
|
# Create test router
|
||||||
test_route = APIRouter(prefix="/test", tags=["Test"])
|
test_route = APIRouter(prefix="/test", tags=["Test"])
|
||||||
|
test_route.include_router(test_route, include_in_schema=True)
|
||||||
|
|
||||||
|
|
||||||
@test_route.get("/health")
|
@test_route.get("/health")
|
||||||
@MiddlewareModule.auth_required
|
@MiddlewareModule.auth_required
|
||||||
async def health_check(request: Request):
|
async def health_check(request: Request):
|
||||||
return {"status": "healthy", "message": "Service is running"}
|
return {"status": "healthy", "message": "Service is running"}
|
||||||
|
|
||||||
|
|
||||||
@test_route.get("/ping")
|
@test_route.get("/ping")
|
||||||
async def ping_test():
|
async def ping_test():
|
||||||
return {"ping": "pong", "service": "base-router"}
|
return {"ping": "pong", "service": "base-router"}
|
||||||
|
|
||||||
# Initialize and include test routes
|
|
||||||
def init_test_routes():
|
|
||||||
return test_route
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@ RUN poetry config virtualenvs.create false \
|
||||||
&& rm -rf ~/.cache/pypoetry
|
&& rm -rf ~/.cache/pypoetry
|
||||||
|
|
||||||
# Copy application code
|
# Copy application code
|
||||||
|
|
||||||
COPY DockerApiServices/AllApiNeeds /app/
|
COPY DockerApiServices/AllApiNeeds /app/
|
||||||
|
COPY ErrorHandlers /app/ErrorHandlers
|
||||||
|
COPY LanguageModels /app/LanguageModels
|
||||||
COPY ApiLibrary /app/ApiLibrary
|
COPY ApiLibrary /app/ApiLibrary
|
||||||
COPY ApiValidations /app/ApiValidations
|
COPY ApiValidations /app/ApiValidations
|
||||||
COPY AllConfigs /app/AllConfigs
|
COPY AllConfigs /app/AllConfigs
|
||||||
|
|
|
||||||
|
|
@ -6,32 +6,32 @@ This repository contains multiple microservices that can be run using Docker Com
|
||||||
For regular development when dependencies haven't changed:
|
For regular development when dependencies haven't changed:
|
||||||
```bash
|
```bash
|
||||||
# Build and run Auth Service
|
# Build and run Auth Service
|
||||||
docker compose -f ../docker-compose-services.yml up auth-service
|
docker compose -f docker-compose-services.yml up auth-service
|
||||||
|
|
||||||
# Build and run Event Service
|
# Build and run Event Service
|
||||||
docker compose -f ../docker-compose-services.yml up event-service
|
docker compose -f docker-compose-services.yml up event-service
|
||||||
|
|
||||||
# Build and run Validation Service
|
# Build and run Validation Service
|
||||||
docker compose -f ../docker-compose-services.yml up validation-service
|
docker compose -f docker-compose-services.yml up validation-service
|
||||||
|
|
||||||
# Build and run all services
|
# Build and run all services
|
||||||
docker compose -f ../docker-compose-services.yml up
|
docker compose -f docker-compose-services.yml up
|
||||||
```
|
```
|
||||||
|
|
||||||
## Clean Build (No Cache)
|
## Clean Build (No Cache)
|
||||||
Use these commands when changing Dockerfile or dependencies:
|
Use these commands when changing Dockerfile or dependencies:
|
||||||
```bash
|
```bash
|
||||||
# Auth Service
|
# Auth Service
|
||||||
docker compose -f ../docker-compose-services.yml build --no-cache auth-service && docker compose -f ../docker-compose-services.yml up auth-service
|
docker compose -f docker-compose-services.yml build --no-cache auth-service && docker compose -f docker-compose-services.yml up auth-service
|
||||||
|
|
||||||
# Event Service
|
# Event Service
|
||||||
docker compose -f ../docker-compose-services.yml build --no-cache event-service && docker compose -f ../docker-compose-services.yml up event-service
|
docker compose -f docker-compose-services.yml build --no-cache event-service && docker compose -f docker-compose-services.yml up event-service
|
||||||
|
|
||||||
# Validation Service
|
# Validation Service
|
||||||
docker compose -f ../docker-compose-services.yml build --no-cache validation-service && docker compose -f ../docker-compose-services.yml up validation-service
|
docker compose -f docker-compose-services.yml build --no-cache validation-service && docker compose -f docker-compose-services.yml up validation-service
|
||||||
|
|
||||||
# All Services
|
# All Services
|
||||||
docker compose -f ../docker-compose-services.yml build --no-cache && docker compose -f ../docker-compose-services.yml up
|
docker compose -f docker-compose-services.yml build --no-cache && docker compose -f docker-compose-services.yml up
|
||||||
```
|
```
|
||||||
|
|
||||||
## Service Ports
|
## Service Ports
|
||||||
|
|
@ -51,9 +51,9 @@ docker compose -f ../docker-compose-services.yml build --no-cache && docker comp
|
||||||
- For faster development iterations
|
- For faster development iterations
|
||||||
- Run in detached mode:
|
- Run in detached mode:
|
||||||
```bash
|
```bash
|
||||||
docker compose -f ../docker-compose-services.yml up -d auth-service
|
docker compose -f docker-compose-services.yml up -d auth-service
|
||||||
```
|
```
|
||||||
- Stop services:
|
- Stop services:
|
||||||
```bash
|
```bash
|
||||||
docker compose -f ../docker-compose-services.yml down
|
docker compose -f docker-compose-services.yml down
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,57 @@
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Union, Awaitable
|
||||||
|
from fastapi import Request, WebSocket
|
||||||
|
from fastapi.responses import Response
|
||||||
|
|
||||||
|
from LanguageModels.Errors.merge_all_error_languages import MergedErrorLanguageModels
|
||||||
from ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
from ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||||
|
from ErrorHandlers.bases import BaseErrorModelClass
|
||||||
|
|
||||||
|
|
||||||
class HTTPExceptionApiHandler:
|
class HTTPExceptionApiHandler:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
**kwargs,
|
response_model: Any,
|
||||||
):
|
):
|
||||||
self.EXCEPTIONS = kwargs.get(
|
self.RESPONSE_MODEL: Any = response_model
|
||||||
"exceptions"
|
|
||||||
) # from fastapi.exceptions import HTTPException
|
|
||||||
self.STATUSES = kwargs.get("statuses") # from fastapi import status
|
|
||||||
self.EXCEPTION_DICTS: Dict = kwargs.get("exceptions_dict")
|
|
||||||
self.ERRORS_DICT: Dict = kwargs.get("errors_dict")
|
|
||||||
self.ERRORS_LANG: Dict = kwargs.get("error_language_dict")
|
|
||||||
self.RESPONSE_MODEL: Any = kwargs.get("response_model")
|
|
||||||
|
|
||||||
def retrieve_error_status_code(self, exc: HTTPExceptionApi):
|
@staticmethod
|
||||||
grab_status = self.ERRORS_DICT.get(str(exc.error_code).upper(), "")
|
def retrieve_error_status_code(exc: HTTPExceptionApi) -> int:
|
||||||
grab_status_code = self.EXCEPTION_DICTS.get(str(grab_status).upper(), "500")
|
from ErrorHandlers import DEFAULT_ERROR
|
||||||
return getattr(
|
error_by_codes = BaseErrorModelClass.retrieve_error_by_codes()
|
||||||
self.STATUSES,
|
grab_status_code = error_by_codes.get(
|
||||||
str(grab_status_code),
|
str(exc.error_code).upper(), DEFAULT_ERROR
|
||||||
getattr(self.STATUSES, "HTTP_500_INTERNAL_SERVER_ERROR"),
|
|
||||||
)
|
)
|
||||||
|
return int(grab_status_code)
|
||||||
|
|
||||||
def retrieve_error_message(self, exc: HTTPExceptionApi):
|
@staticmethod
|
||||||
message_by_lang = self.ERRORS_LANG.get(str(exc.lang).lower(), {})
|
def retrieve_error_message(exc: HTTPExceptionApi, error_languages) -> str:
|
||||||
return message_by_lang.get(str(exc.error_code).upper(), "Unknown error")
|
from ErrorHandlers import DEFAULT_ERROR
|
||||||
|
return error_languages.get(str(exc.error_code).upper(), DEFAULT_ERROR)
|
||||||
|
|
||||||
def handle_exception(self, request, exc: HTTPExceptionApi):
|
async def handle_exception(
|
||||||
|
self, request: Union[Request, WebSocket], exc: Exception
|
||||||
|
) -> Union[Response, Awaitable[None]]:
|
||||||
|
request_string = str(request.url) if isinstance(request, Request) else request.url.path
|
||||||
|
if isinstance(exc, HTTPExceptionApi):
|
||||||
|
error_languages = MergedErrorLanguageModels.get_language_models(
|
||||||
|
language=exc.lang
|
||||||
|
)
|
||||||
status_code = self.retrieve_error_status_code(exc)
|
status_code = self.retrieve_error_status_code(exc)
|
||||||
error_message = self.retrieve_error_message(exc)
|
error_message = self.retrieve_error_message(exc, error_languages)
|
||||||
return self.RESPONSE_MODEL(
|
return self.RESPONSE_MODEL(
|
||||||
status_code=int(status_code),
|
status_code=int(status_code),
|
||||||
content={"message": error_message, "lang": exc.lang, "request": request},
|
content={
|
||||||
|
"message": error_message,
|
||||||
|
"lang": exc.lang,
|
||||||
|
"request": request_string,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
return self.RESPONSE_MODEL(
|
||||||
|
status_code=500,
|
||||||
|
content={
|
||||||
|
"message": "Internal Server Error",
|
||||||
|
"lang": "def",
|
||||||
|
"request": request_string,
|
||||||
|
},
|
||||||
|
) # Handle other exceptions with a generic 500 error
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,10 @@ from ErrorHandlers.ErrorHandlers.api_exc_handler import (
|
||||||
from ErrorHandlers.Exceptions.api_exc import (
|
from ErrorHandlers.Exceptions.api_exc import (
|
||||||
HTTPExceptionApi,
|
HTTPExceptionApi,
|
||||||
)
|
)
|
||||||
|
DEFAULT_ERROR = "UNKNOWN_ERROR"
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"HTTPExceptionApiHandler",
|
"HTTPExceptionApiHandler",
|
||||||
"HTTPExceptionApi",
|
"HTTPExceptionApi",
|
||||||
|
"DEFAULT_ERROR"
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
from ErrorHandlers.bases import BaseErrorModelClass
|
class BaseError:
|
||||||
|
|
||||||
|
|
||||||
class BaseError(BaseErrorModelClass):
|
|
||||||
NOT_CREATED: int = 405
|
NOT_CREATED: int = 405
|
||||||
NOT_DELETED: int = 405
|
NOT_DELETED: int = 405
|
||||||
NOT_UPDATED: int = 405
|
NOT_UPDATED: int = 405
|
||||||
|
|
@ -14,3 +11,4 @@ class BaseError(BaseErrorModelClass):
|
||||||
NOT_ACCEPTABLE: int = 406
|
NOT_ACCEPTABLE: int = 406
|
||||||
INVALID_DATA: int = 422
|
INVALID_DATA: int = 422
|
||||||
UNKNOWN_ERROR: int = 502
|
UNKNOWN_ERROR: int = 502
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,19 @@
|
||||||
from typing import Optional
|
from ErrorHandlers.base import BaseError
|
||||||
|
from ErrorHandlers.statuses import Statuses
|
||||||
|
|
||||||
|
|
||||||
class BaseErrorModelClass:
|
class BaseErrorModelClass:
|
||||||
|
list_of_statuses = [Statuses, BaseError]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def retrieve_error_by_code(cls, error_code: str):
|
def retrieve_error_by_codes(cls):
|
||||||
return getattr(cls, error_code, 502)
|
language_model_status = {}
|
||||||
|
for list_of_language in cls.list_of_statuses:
|
||||||
|
clean_dict = {
|
||||||
|
key: value
|
||||||
|
for key, value in list_of_language.__dict__.items()
|
||||||
|
if "__" not in str(key)[0:3]
|
||||||
|
}
|
||||||
|
language_model_status.update(clean_dict)
|
||||||
|
return language_model_status
|
||||||
|
|
||||||
|
|
||||||
class StatusesModelClass:
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def retrieve_error_by_code(cls, error_code: str):
|
|
||||||
return getattr(cls, error_code, 502)
|
|
||||||
|
|
||||||
|
|
||||||
class ErrorLanguageModelClass:
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def retrieve_error_header(cls, error_code: str):
|
|
||||||
return getattr(cls, error_code, "Unknown Error occured.")
|
|
||||||
|
|
||||||
|
|
||||||
class LanguageModelClass:
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def retrieve_error_by_code(cls, error_code: str, language: Optional[str] = "tr"):
|
|
||||||
language_model: ErrorLanguageModelClass = getattr(cls, language, "tr")
|
|
||||||
return language_model.retrieve_error_header(error_code)
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
from ErrorHandlers.bases import StatusesModelClass
|
class Statuses:
|
||||||
|
|
||||||
|
|
||||||
class Statuses(StatusesModelClass):
|
|
||||||
HTTP_100_CONTINUE = 100
|
HTTP_100_CONTINUE = 100
|
||||||
HTTP_101_SWITCHING_PROTOCOLS = 101
|
HTTP_101_SWITCHING_PROTOCOLS = 101
|
||||||
HTTP_102_PROCESSING = 102
|
HTTP_102_PROCESSING = 102
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
from LanguageModels.Errors.base_languages import BaseErrorLanguageModels
|
from .merge_all_error_languages import MergedErrorLanguageModels
|
||||||
|
|
||||||
__all__ = ["BaseErrorLanguageModels"]
|
__all__ = ["MergedErrorLanguageModels"]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
from ErrorHandlers.bases import ErrorLanguageModelClass, LanguageModelClass
|
class BaseErrorLanguageModelTurkish:
|
||||||
|
|
||||||
|
|
||||||
class BaseErrorLanguageModelTurkish(ErrorLanguageModelClass):
|
|
||||||
|
|
||||||
NOT_CREATED: str = "Kayıt oluşturulamadı."
|
NOT_CREATED: str = "Kayıt oluşturulamadı."
|
||||||
NOT_DELETED: str = "Kayıt silinemedi."
|
NOT_DELETED: str = "Kayıt silinemedi."
|
||||||
|
|
@ -17,7 +14,7 @@ class BaseErrorLanguageModelTurkish(ErrorLanguageModelClass):
|
||||||
UNKNOWN_ERROR: str = "Bilinmeyen bir hata oluştu."
|
UNKNOWN_ERROR: str = "Bilinmeyen bir hata oluştu."
|
||||||
|
|
||||||
|
|
||||||
class BaseErrorLanguageModelEnglish(ErrorLanguageModelClass):
|
class BaseErrorLanguageModelEnglish:
|
||||||
|
|
||||||
NOT_CREATED: str = "Not Created."
|
NOT_CREATED: str = "Not Created."
|
||||||
NOT_DELETED: str = "Not Deleted."
|
NOT_DELETED: str = "Not Deleted."
|
||||||
|
|
@ -33,6 +30,6 @@ class BaseErrorLanguageModelEnglish(ErrorLanguageModelClass):
|
||||||
UNKNOWN_ERROR: str = "Unknown Error occured."
|
UNKNOWN_ERROR: str = "Unknown Error occured."
|
||||||
|
|
||||||
|
|
||||||
class BaseErrorLanguageModels(LanguageModelClass):
|
class BaseErrorLanguageModels:
|
||||||
tr: BaseErrorLanguageModelTurkish = BaseErrorLanguageModelTurkish
|
tr: BaseErrorLanguageModelTurkish = BaseErrorLanguageModelTurkish
|
||||||
en: BaseErrorLanguageModelEnglish = BaseErrorLanguageModelEnglish
|
en: BaseErrorLanguageModelEnglish = BaseErrorLanguageModelEnglish
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
from LanguageModels.Errors.base_languages import BaseErrorLanguageModels
|
||||||
|
|
||||||
|
|
||||||
|
class MergedErrorLanguageModels:
|
||||||
|
list_of_languages = [BaseErrorLanguageModels]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_language_models(cls, language: str):
|
||||||
|
language_model_keys = {}
|
||||||
|
for list_of_language in cls.list_of_languages:
|
||||||
|
language_model_class = getattr(list_of_language, language, None)
|
||||||
|
clean_dict = {
|
||||||
|
key: value
|
||||||
|
for key, value in language_model_class.__dict__.items()
|
||||||
|
if "__" not in str(key)[0:3]
|
||||||
|
}
|
||||||
|
language_model_keys.update(clean_dict)
|
||||||
|
return language_model_keys
|
||||||
Loading…
Reference in New Issue