From 5b06b80046c42aa2dd43df18a8a8b29c4c7e546e Mon Sep 17 00:00:00 2001 From: grey-cat-1908 Date: Sun, 13 Mar 2022 10:42:51 +0300 Subject: [PATCH] something with http exceptions --- melisa/core/gateway.py | 20 +++++++++ melisa/core/http.py | 23 +++++++++++ melisa/exceptions.py | 84 ++++++++++++++++++++++++++++++++++++++ melisa/models/__init__.py | 6 ++- melisa/models/app/error.py | 83 ------------------------------------- 5 files changed, 132 insertions(+), 84 deletions(-) create mode 100644 melisa/exceptions.py delete mode 100644 melisa/models/app/error.py diff --git a/melisa/core/gateway.py b/melisa/core/gateway.py index 94ccdb8..73bb6f4 100644 --- a/melisa/core/gateway.py +++ b/melisa/core/gateway.py @@ -2,10 +2,13 @@ import json import asyncio import zlib import time +from asyncio import ensure_future from dataclasses import dataclass +from typing import Dict, Any import websockets +from ..exceptions import InvalidPayload, GatewayError, PrivilegedIntentsRequired, LoginFailure from ..listeners import listeners from ..models.user import BotActivity from ..utils import APIObjectBase @@ -49,6 +52,23 @@ class Gateway: self.latency = float('inf') self.connected = False + self.__close_codes: Dict[int, Any] = { + 4001: GatewayError("Invalid opcode was sent"), + 4002: InvalidPayload("Invalid payload was sent."), + 4003: GatewayError("Payload was sent prior to identifying"), + 4004: LoginFailure("Token is not valid"), + 4005: GatewayError( + "Authentication was sent after client already authenticated" + ), + 4007: GatewayError("Invalid sequence sent when starting new session"), + 4008: GatewayError("Client was rate limited"), + 4010: GatewayError("Invalid shard"), + 4011: GatewayError("Sharding required"), + 4012: GatewayError("Invalid API version"), + 4013: GatewayError("Invalid intents"), + 4014: PrivilegedIntentsRequired("Disallowed intents") + } + self.listeners = listeners self._last_send = 0 diff --git a/melisa/core/http.py b/melisa/core/http.py index e668512..b6fcb54 100644 --- a/melisa/core/http.py +++ b/melisa/core/http.py @@ -5,6 +5,14 @@ from typing import Dict, Optional, Union, Any from aiohttp import ClientSession, ClientResponse +from melisa.exceptions import (NotModifiedError, + BadRequestError, + ForbiddenError, + UnauthorizedError, + HTTPException, + NotFoundError, + MethodNotAllowedError) + class HTTPClient: def __init__(self, token: str, *, ttl: int = 5): @@ -17,6 +25,15 @@ class HTTPClient: "User-Agent": f"Melisa Python Library" } + self.__http_exceptions: Dict[int, HTTPException] = { + 304: NotModifiedError(), + 400: BadRequestError(), + 401: UnauthorizedError(), + 403: ForbiddenError(), + 404: NotFoundError(), + 405: MethodNotAllowedError() + } + self.__aiohttp_session: ClientSession = ClientSession(headers=headers) async def close(self): @@ -55,6 +72,12 @@ class HTTPClient: if res.ok: return await res.json() + exception = self.__http_exceptions.get(res.status) + + if exception: + exception.__init__(res.reason) + raise exception + retry_in = 1 + (self.max_ttl - _ttl) * 2 await asyncio.sleep(retry_in) diff --git a/melisa/exceptions.py b/melisa/exceptions.py new file mode 100644 index 0000000..8481fbb --- /dev/null +++ b/melisa/exceptions.py @@ -0,0 +1,84 @@ +class MelisaException(Exception): + """Base exception""" + pass + + +class ClientException(MelisaException): + """Handling user errors""" + pass + + +class InvalidPayload(MelisaException): + """This exception means invalid payload""" + pass + + +class LoginFailure(ClientException): + """Fails to log you in from improper credentials or some other misc.""" + pass + + +class ConnectionClosed(ClientException): + """Exception that's thrown when the gateway connection is closed for reasons that could not be handled + internally. """ + + def __init__(self, socket, *, shard_id, code=None): + message = "Websocket with shard ID {} closed with code {}" + self.code = code or socket.close_code + self.shard_id = shard_id + + super().__init__(message.format(self.shard_id, self.code)) + + +class PrivilegedIntentsRequired(ClientException): + """Occurs when the gateway requests privileged intents, but they are not yet marked on the developer page. + + Visit to https://discord.com/developers/applications/ + """ + + def __init__(self, shard_id): + self.shard_id = shard_id + message = "Shard ID {} is requesting privileged intents that have not been explicitly enabled in the " \ + "developer portal. Please visit to https://discord.com/developers/applications/ " + + super().__init__(message.format(self.shard_id)) + + +class HTTPException(MelisaException): + """Occurs when an HTTP request operation fails.""" + + +class NotModifiedError(HTTPException): + """Error code 304.""" + + +class BadRequestError(HTTPException): + """Error code 400.""" + + +class UnauthorizedError(HTTPException): + """Error code 401.""" + + +class ForbiddenError(HTTPException): + """Error code 403.""" + + +class NotFoundError(HTTPException): + """Error code 404.""" + + +class MethodNotAllowedError(HTTPException): + """Error code 405.""" + + +class RateLimitError(HTTPException): + """Error code 429.""" + + +class GatewayError(HTTPException): + """Error code 502.""" + + +class ServerError(HTTPException): + """Error code 5xx.""" diff --git a/melisa/models/__init__.py b/melisa/models/__init__.py index 0e7a5aa..6b25cdd 100644 --- a/melisa/models/__init__.py +++ b/melisa/models/__init__.py @@ -1 +1,5 @@ -from .app import Intents +from .app import * +from .guild import * +from .user import * + + diff --git a/melisa/models/app/error.py b/melisa/models/app/error.py deleted file mode 100644 index 8c2ff8e..0000000 --- a/melisa/models/app/error.py +++ /dev/null @@ -1,83 +0,0 @@ -# i not like PEP8, sorry - -class MelisaException(Exception): - """Base exception""" - pass - - -class NoMoreItems(MelisaException): - """Occurs when there are no more elements in an asynchronous iterative operation""" - pass - - -class NotFoundGateway(MelisaException): - """Occurs when the gateway for the websocket was not found""" - def __init__(self): - message = "The gateway to connect to Discord was not found" - - super().__init__(message) - - -class ClientException(MelisaException): - """Handling user errors""" - pass - - - -class InvalidData(ClientException): - """Unknown or invalid data from Discord""" - pass - - -class LoginFailure(ClientException): - """Fails to log you in from improper credentials or some other misc.""" - pass - - -class ConnectionClosed(ClientException): - """Exception that's thrown when the gateway connection is closed for reasons that could not be handled internally.""" - def __init__(self, socket, *, shard_id, code=None): - message = "Websocket with shard ID {} closed with code {}" - self.code = code or socket.close_code - self.shard_id = shard_id - - super().__init__(message.format(self.shard_id, self.code)) - - -class PrivilegedIntentsRequired(ClientException): - """Occurs when the gateway requests privileged intents, but they are not yet marked on the developer page. - - Visit to https://discord.com/developers/applications/ - """ - - def __init__(self, shard_id): - self.shard_id = shard_id - message = "Shard ID {} is requesting privileged intents that have not been explicitly enabled in the developer portal. Please visit to https://discord.com/developers/applications/ " - - super().__init__(message.format(self.shard_id)) - - -class HttpException(MelisaException): - """Occurs when an HTTP request operation fails.""" - - def __init__(self, response): - self.responce = response - self.status = response.status - message = "{} with responce status {}" - - super().__init__(message.format(self.responce, self.status)) - - -class DiscordErrorServer(HttpException): - """Error that is issued when the status code 500""" - pass - - -class NotFound(HttpException): - """Error that is issued when the status code 404""" - pass - - -class Forbidden(HttpException): - """Error that is issued when the status code 403""" - pass