refactored
Some checks failed
Deploy on push / deploy (push) Failing after 6s

This commit is contained in:
2025-08-17 17:56:31 +03:00
parent e78e12eeee
commit 9a2b792f08
98 changed files with 702 additions and 904 deletions

48
utils/common_result.py Normal file
View File

@@ -0,0 +1,48 @@
from dataclasses import dataclass
from typing import Any
from graphql.error import GraphQLError
# Импорт Author отложен для избежания циклических импортов
from orm.community import Community
from orm.draft import Draft
from orm.reaction import Reaction
from orm.shout import Shout
from orm.topic import Topic
from utils.logger import root_logger as logger
def handle_error(operation: str, error: Exception) -> GraphQLError:
"""Обрабатывает ошибки в резолверах"""
logger.error(f"Ошибка при {operation}: {error}")
return GraphQLError(f"Не удалось {operation}: {error}")
@dataclass
class CommonResult:
"""Общий результат для GraphQL запросов"""
error: str | None = None
drafts: list[Draft] | None = None # Draft objects
draft: Draft | None = None # Draft object
slugs: list[str] | None = None
shout: Shout | None = None
shouts: list[Shout] | None = None
author: Any | None = None # Author type resolved at runtime
authors: list[Any] | None = None # Author type resolved at runtime
reaction: Reaction | None = None
reactions: list[Reaction] | None = None
topic: Topic | None = None
topics: list[Topic] | None = None
community: Community | None = None
communities: list[Community] | None = None
@dataclass
class AuthorFollowsResult:
"""Результат для get_author_follows запроса"""
topics: list[Any] | None = None # Topic dicts
authors: list[Any] | None = None # Author dicts
communities: list[Any] | None = None # Community dicts
error: str | None = None

View File

@@ -4,7 +4,7 @@ JSON encoders and utilities
import json
from datetime import date, datetime
from typing import Any, Union
from typing import Any
import orjson
@@ -23,7 +23,7 @@ def default_json_encoder(obj: Any) -> Any:
TypeError: Если объект не может быть сериализован
"""
# Обработка datetime
if isinstance(obj, (datetime, date)):
if isinstance(obj, (datetime | date)):
return obj.isoformat()
serialized = False
@@ -75,7 +75,7 @@ def orjson_dumps(obj: Any, **kwargs: Any) -> bytes:
return orjson.dumps(obj, default=default_json_encoder, **kwargs)
def orjson_loads(data: Union[str, bytes]) -> Any:
def orjson_loads(data: str | bytes) -> Any:
"""
Десериализация объекта с помощью orjson.

22
utils/exception.py Normal file
View File

@@ -0,0 +1,22 @@
import logging
from collections.abc import Awaitable
from typing import Callable
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse, Response
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
class ExceptionHandlerMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
try:
return await call_next(request)
except Exception:
logger.exception("Unhandled exception occurred")
return JSONResponse(
{"detail": "An error occurred. Please try again later."},
status_code=500,
)

View File

@@ -2,7 +2,7 @@ import re
from urllib.parse import quote_plus
from auth.orm import Author
from services.db import local_session
from storage.db import local_session
def replace_translit(src: str | None) -> str:

30
utils/sentry.py Normal file
View File

@@ -0,0 +1,30 @@
import logging
import sentry_sdk
from sentry_sdk.integrations.ariadne import AriadneIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from sentry_sdk.integrations.starlette import StarletteIntegration
from settings import GLITCHTIP_DSN
logger = logging.getLogger(__name__)
# Настройка логирования для отправки логов в Sentry
sentry_logging_handler = sentry_sdk.integrations.logging.SentryHandler(level=logging.WARNING)
logger.addHandler(sentry_logging_handler)
logger.setLevel(logging.DEBUG) # Более подробное логирование
def start_sentry() -> None:
try:
logger.info("[utils.sentry] Sentry init started...")
sentry_sdk.init(
dsn=GLITCHTIP_DSN,
traces_sample_rate=1.0, # Захват 100% транзакций
profiles_sample_rate=1.0, # Профилирование 100% транзакций
enable_tracing=True,
integrations=[StarletteIntegration(), AriadneIntegration(), SqlalchemyIntegration()],
send_default_pii=True, # Отправка информации о пользователе (PII)
)
logger.info("[utils.sentry] Sentry initialized successfully.")
except (sentry_sdk.utils.BadDsn, ImportError, ValueError, TypeError) as _e:
logger.warning("[utils.sentry] Failed to initialize Sentry", exc_info=True)