altrepo: add error handling

parent 4cd86a40
class RequestValidationError(Exception):
"""Ошибка валидации параметров запроса (400)"""
pass
class DataNotFoundError(Exception):
"""Данные не найдены в базе (404)"""
pass
class TooManyRequests(Exception):
"""Cлишком много запросо (429)"""
pass
class UnexpectedResponseError(Exception):
"""Непредвиденный ответ от сервера"""
def __init__(self, status_code: int, message: str = ""):
self.status_code = status_code
self.message = message or f"Unexpected response status: {status_code}"
super().__init__(self.message)
...@@ -4,6 +4,7 @@ from urllib.parse import urlencode ...@@ -4,6 +4,7 @@ from urllib.parse import urlencode
from typing import List from typing import List
from . import models from . import models
from . import errors
class BaseAPI: class BaseAPI:
...@@ -12,6 +13,24 @@ class BaseAPI: ...@@ -12,6 +13,24 @@ class BaseAPI:
def __init__(self, session: aiohttp.ClientSession): def __init__(self, session: aiohttp.ClientSession):
self.session = session self.session = session
async def _handle_response(self, resp: aiohttp.ClientResponse):
match resp.status:
case 200 | 201:
return await resp.json()
case 400:
raise errors.RequestValidationError("Request parameters validation error (400)")
case 404:
raise errors.DataNotFoundError("Requested data not found in database (404)")
case 429:
raise errors.TooManyRequests("Too Many Requests (429)")
case _:
try:
error_text = await resp.text()
except:
error_text = ""
raise errors.UnexpectedResponseError(resp.status, error_text)
async def get(self, path: str, params: dict = None): async def get(self, path: str, params: dict = None):
url = f"{self.BASE_URL}/{path.lstrip('/')}" url = f"{self.BASE_URL}/{path.lstrip('/')}"
if params: if params:
...@@ -19,15 +38,13 @@ class BaseAPI: ...@@ -19,15 +38,13 @@ class BaseAPI:
v, list) else v for k, v in params.items()}) v, list) else v for k, v in params.items()})
url += f"?{query}" url += f"?{query}"
async with self.session.get(url) as resp: async with self.session.get(url) as resp:
resp.raise_for_status() return await self._handle_response(resp)
return await resp.json()
async def post(self, path: str, data: dict = None, json: dict = None): async def post(self, path: str, data: dict = None, json: dict = None):
url = f"{self.BASE_URL}/{path.lstrip('/')}" url = f"{self.BASE_URL}/{path.lstrip('/')}"
async with self.session.post(url, data=data, json=json) as resp: async with self.session.post(url, data=data, json=json) as resp:
resp.raise_for_status() return await self._handle_response(resp)
return await resp.json()
class APIInfo: class APIInfo:
......
from telegrinder import API, Telegrinder, Token from telegrinder import API, Telegrinder, Token, Message
from telegrinder.modules import logger from telegrinder.modules import logger
from telegrinder.tools.formatting import HTMLFormatter from telegrinder.tools.formatting import HTMLFormatter
from telegrinder.types import LinkPreviewOptions from telegrinder.types import LinkPreviewOptions
from telegrinder.node import Error
from config import config from config import config
from altrepo import altrepo from altrepo import altrepo
from altrepo.api.errors import TooManyRequests
from database.models import db, User from database.models import db, User
from middlewares import UserMiddleware from middlewares import UserMiddleware
...@@ -29,4 +31,8 @@ async def shutdown(): ...@@ -29,4 +31,8 @@ async def shutdown():
logger.info("stopping ALTRepo") logger.info("stopping ALTRepo")
await altrepo.close() await altrepo.close()
@bot.on.error()
async def error_handler(err: Error[TooManyRequests], m: Message):
await m.answer(f"Слишком много запросов!")
bot.run_forever(skip_updates=True) bot.run_forever(skip_updates=True)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment