hikari.errors
Exceptions and warnings that can be thrown by this library.
View Source
# -*- coding: utf-8 -*- # cython: language_level=3 # Copyright (c) 2020 Nekokatt # Copyright (c) 2021-present davfsa # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """Exceptions and warnings that can be thrown by this library.""" from __future__ import annotations __all__: typing.Sequence[str] = ( "HikariError", "HikariWarning", "HikariInterrupt", "ComponentStateConflictError", "UnrecognisedEntityError", "NotFoundError", "RateLimitedError", "RateLimitTooLongError", "UnauthorizedError", "ForbiddenError", "BadRequestError", "HTTPError", "HTTPResponseError", "ClientHTTPResponseError", "InternalServerError", "ShardCloseCode", "GatewayConnectionError", "GatewayServerClosedConnectionError", "GatewayError", "MissingIntentWarning", "MissingIntentError", "BulkDeleteError", "VoiceError", ) import http import typing import attr from hikari.internal import attr_extensions from hikari.internal import data_binding from hikari.internal import enums if typing.TYPE_CHECKING: from hikari import intents as intents_ from hikari import messages from hikari import snowflakes from hikari.internal import routes # The standard exceptions are all unsloted so slotting here would be a waste of time. @attr_extensions.with_copy @attr.define(auto_exc=True, repr=False, init=False, slots=False) class HikariError(RuntimeError): """Base for an error raised by this API. Any exceptions should derive from this. .. note:: You should never initialize this exception directly. """ # The standard warnings are all unsloted so slotting here would be a waste of time. @attr_extensions.with_copy @attr.define(auto_exc=True, repr=False, init=False, slots=False) class HikariWarning(RuntimeWarning): """Base for a warning raised by this API. Any warnings should derive from this. .. note:: You should never initialize this warning directly. """ @attr.define(auto_exc=True, repr=False, slots=False) class HikariInterrupt(KeyboardInterrupt, HikariError): """Exception raised when a kill signal is handled internally.""" signum: int = attr.field() """The signal number that was raised.""" signame: str = attr.field() """The signal name that was raised.""" @attr.define(auto_exc=True, repr=False, slots=False) class ComponentStateConflictError(HikariError): """Exception thrown when an action cannot be executed in the component's current state. Dependent on context this will be thrown for components which are already running or haven't been started yet. """ reason: str = attr.field() """A string to explain the issue.""" def __str__(self) -> str: return self.reason @attr.define(auto_exc=True, repr=False, slots=False) class UnrecognisedEntityError(HikariError): """An exception thrown when an unrecognised entity is found.""" reason: str = attr.field() """A string to explain the issue.""" def __str__(self) -> str: return self.reason @attr.define(auto_exc=True, repr=False, slots=False) class GatewayError(HikariError): """A base exception type for anything that can be thrown by the Gateway.""" reason: str = attr.field() """A string to explain the issue.""" def __str__(self) -> str: return self.reason @typing.final class ShardCloseCode(int, enums.Enum): """Reasons for a shard connection closure.""" NORMAL_CLOSURE = 1_000 GOING_AWAY = 1_001 PROTOCOL_ERROR = 1_002 TYPE_ERROR = 1_003 ENCODING_ERROR = 1_007 POLICY_VIOLATION = 1_008 TOO_BIG = 1_009 UNEXPECTED_CONDITION = 1_011 UNKNOWN_ERROR = 4_000 UNKNOWN_OPCODE = 4_001 DECODE_ERROR = 4_002 NOT_AUTHENTICATED = 4_003 AUTHENTICATION_FAILED = 4_004 ALREADY_AUTHENTICATED = 4_005 INVALID_SEQ = 4_007 RATE_LIMITED = 4_008 SESSION_TIMEOUT = 4_009 INVALID_SHARD = 4_010 SHARDING_REQUIRED = 4_011 INVALID_VERSION = 4_012 INVALID_INTENT = 4_013 DISALLOWED_INTENT = 4_014 @property def is_standard(self) -> bool: """Return `True` if this is a standard code.""" return (self.value // 1000) == 1 @attr.define(auto_exc=True, repr=False, slots=False) class GatewayConnectionError(GatewayError): """An exception thrown if a connection issue occurs.""" def __str__(self) -> str: return f"Failed to connect to server: {self.reason!r}" @attr.define(auto_exc=True, repr=False, slots=False) class GatewayServerClosedConnectionError(GatewayError): """An exception raised when the server closes the connection.""" code: typing.Union[ShardCloseCode, int, None] = attr.field(default=None) """Return the close code that was received, if there is one. Returns ------- typing.Union[ShardCloseCode, int, None] The shard close code if there was one. Will be a `ShardCloseCode` if the definition is known. Undocumented close codes may instead be an `int` instead. If no close code was received, this will be `None`. """ can_reconnect: bool = attr.field(default=False) """Return `True` if we can recover from this closure. If `True`, it will try to reconnect after this is raised rather than it being propagated to the caller. If `False`, this will be raised, thus stopping the application unless handled explicitly by the user. Returns ------- bool Whether the closure can be recovered from via a reconnect. """ def __str__(self) -> str: return f"Server closed connection with code {self.code} ({self.reason})" @attr.define(auto_exc=True, repr=False, slots=False) class HTTPError(HikariError): """Base exception raised if an HTTP error occurs while making a request.""" message: str = attr.field() """The error message.""" @attr.define(auto_exc=True, repr=False, slots=False) class HTTPResponseError(HTTPError): """Base exception for an erroneous HTTP response.""" url: str = attr.field() """The URL that produced this error message.""" status: http.HTTPStatus = attr.field() """The HTTP status code for the response.""" headers: data_binding.Headers = attr.field() """The headers received in the error response.""" raw_body: typing.Any = attr.field() """The response body.""" message: str = attr.field(default="") """The error message.""" code: int = attr.field(default=0) """The error code.""" def __str__(self) -> str: name = self.status.name.replace("_", " ").title() name_value = f"{name} {self.status.value}" if self.code: code_str = f" ({self.code})" else: code_str = "" if self.message: body = self.message else: try: body = self.raw_body.decode("utf-8") except (AttributeError, UnicodeDecodeError, TypeError, ValueError): body = str(self.raw_body) chomped = len(body) > 200 return f"{name_value}:{code_str} '{body[:200]}{'...' if chomped else ''}' for {self.url}" @attr.define(auto_exc=True, repr=False, slots=False) class ClientHTTPResponseError(HTTPResponseError): """Base exception for an erroneous HTTP response that is a client error. All exceptions derived from this base should be treated as 4xx client errors when encountered. """ @attr.define(auto_exc=True, repr=False, slots=False) class BadRequestError(ClientHTTPResponseError): """Raised when you send an invalid request somehow.""" status: http.HTTPStatus = attr.field(default=http.HTTPStatus.BAD_REQUEST, init=False) """The HTTP status code for the response.""" errors: typing.Optional[typing.Dict[str, data_binding.JSONObject]] = attr.field(default=None, kw_only=True) """Dict of top level field names to field specific error paths. For more information, this error format is loosely defined at <https://discord.com/developers/docs/reference#error-messages> and is commonly returned for 50035 errors. """ _cached_str: str = attr.field(default=None, init=False) def __str__(self) -> str: if self._cached_str: return self._cached_str value = super().__str__() if self.errors: value += "\n" + data_binding.dump_json(self.errors, indent=2) self._cached_str = value return value @attr.define(auto_exc=True, repr=False, slots=False) class UnauthorizedError(ClientHTTPResponseError): """Raised when you are not authorized to access a specific resource.""" status: http.HTTPStatus = attr.field(default=http.HTTPStatus.UNAUTHORIZED, init=False) """The HTTP status code for the response.""" @attr.define(auto_exc=True, repr=False, slots=False) class ForbiddenError(ClientHTTPResponseError): """Raised when you are not allowed to access a specific resource. This means you lack the permissions to do something, either because of permissions set in a guild, or because your application is not whitelisted to use a specific endpoint. """ status: http.HTTPStatus = attr.field(default=http.HTTPStatus.FORBIDDEN, init=False) """The HTTP status code for the response.""" @attr.define(auto_exc=True, repr=False, slots=False) class NotFoundError(ClientHTTPResponseError): """Raised when something is not found.""" status: http.HTTPStatus = attr.field(default=http.HTTPStatus.NOT_FOUND, init=False) """The HTTP status code for the response.""" @attr.define(auto_exc=True, kw_only=True, repr=False, slots=False) class RateLimitedError(ClientHTTPResponseError): """Raised when a non-global rate limit that cannot be handled occurs. If you receive one of these, you should NOT try again until the given time has passed, either discarding the operation you performed, or waiting until the given time has passed first. Note that it may still be valid to send requests with different attributes in them. A use case for this by Discord appears to be to stop abuse from bots that change channel names, etc, regularly. This kind of action allegedly causes a fair amount of overhead internally for Discord. In the case you encounter this, you may be able to send different requests that manipulate the same entities (in this case editing the same channel) that do not use the same collection of attributes as the previous request. """ route: routes.CompiledRoute = attr.field() """The route that produced this error.""" retry_after: float = attr.field() """How many seconds to wait before you can reuse the route with the specific request.""" status: http.HTTPStatus = attr.field(default=http.HTTPStatus.TOO_MANY_REQUESTS, init=False) """The HTTP status code for the response.""" message: str = attr.field(init=False) """The error message.""" @message.default def _(self) -> str: return f"You are being rate-limited for {self.retry_after:,} seconds on route {self.route}. Please slow down!" @attr.define(auto_exc=True, kw_only=True, repr=False, slots=False) class RateLimitTooLongError(HTTPError): """Internal error raised if the wait for a rate limit is too long. This is similar to `asyncio.TimeoutError` in the way that it is used, but this will be raised pre-emptively and immediately if the period of time needed to wait is greater than a user-defined limit. This will almost always be route-specific. If you receive this, it is unlikely that performing the same call for a different channel/guild/user will also have this rate limit. """ route: routes.CompiledRoute = attr.field() """The route that produced this error.""" retry_after: float = attr.field() """How many seconds to wait before you can retry this specific request.""" max_retry_after: float = attr.field() """How long the client is allowed to wait for at a maximum before raising.""" reset_at: float = attr.field() """UNIX timestamp of when this limit will be lifted.""" limit: int = attr.field() """The maximum number of calls per window for this rate limit.""" period: float = attr.field() """How long the rate limit window lasts for from start to end.""" message: str = attr.field(init=False) """The error message.""" @message.default def _(self) -> str: return ( "The request has been rejected, as you would be waiting for more than" f"the max retry-after ({self.max_retry_after}) on route {self.route}" ) # This may support other types of limits in the future, this currently # exists to be self-documenting to the user and for future compatibility # only. @property def remaining(self) -> typing.Literal[0]: """Remaining requests in this window. This will always be `0` symbolically. """ return 0 def __str__(self) -> str: return self.message @attr.define(auto_exc=True, repr=False, slots=False) class InternalServerError(HTTPResponseError): """Base exception for an erroneous HTTP response that is a server error. All exceptions derived from this base should be treated as 5xx server errors when encountered. If you get one of these, it is not your fault! """ @attr.define(auto_exc=True, repr=False, init=False, slots=False) class MissingIntentWarning(HikariWarning): """Warning raised when subscribing to an event that cannot be fired. This is caused by your application missing certain intents. """ @attr.define(auto_exc=True, repr=False, slots=False) class BulkDeleteError(HikariError): """Exception raised when a bulk delete fails midway through a call. This will contain the list of message items that failed to be deleted, and will have a cause containing the initial exception. """ messages_deleted: snowflakes.SnowflakeishSequence[messages.PartialMessage] = attr.field() """Any message objects that were deleted before an exception occurred.""" messages_skipped: snowflakes.SnowflakeishSequence[messages.PartialMessage] = attr.field() """Any message objects that were skipped due to an exception.""" @property def percentage_completion(self) -> float: """Return the percentage completion of the bulk delete before it failed.""" deleted = len(self.messages_deleted) total = deleted + len(self.messages_skipped) return 100 * deleted / total def __str__(self) -> str: deleted = len(self.messages_deleted) total = deleted + len(self.messages_skipped) return f"Error encountered when bulk deleting messages ({deleted}/{total} messages deleted)" @attr.define(auto_exc=True, repr=False, init=False, slots=False) class VoiceError(HikariError): """Error raised when a problem occurs with the voice subsystem.""" @attr.define(auto_exc=True, repr=False, slots=False) class MissingIntentError(HikariError, ValueError): """Error raised when you try to perform an action without an intent. This is usually raised when querying the cache for something that is unavailable due to certain intents being disabled. """ intents: intents_.Intents = attr.field() """The combination of intents that are missing.""" def __str__(self) -> str: return "You are missing the following intent(s): " + ", ".join(map(str, self.intents.split()))
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class BadRequestError(ClientHTTPResponseError): """Raised when you send an invalid request somehow.""" status: http.HTTPStatus = attr.field(default=http.HTTPStatus.BAD_REQUEST, init=False) """The HTTP status code for the response.""" errors: typing.Optional[typing.Dict[str, data_binding.JSONObject]] = attr.field(default=None, kw_only=True) """Dict of top level field names to field specific error paths. For more information, this error format is loosely defined at <https://discord.com/developers/docs/reference#error-messages> and is commonly returned for 50035 errors. """ _cached_str: str = attr.field(default=None, init=False) def __str__(self) -> str: if self._cached_str: return self._cached_str value = super().__str__() if self.errors: value += "\n" + data_binding.dump_json(self.errors, indent=2) self._cached_str = value return value
Raised when you send an invalid request somehow.
Variables and properties
The error code.
Dict of top level field names to field specific error paths.
For more information, this error format is loosely defined at https://discord.com/developers/docs/reference#error-messages and is commonly returned for 50035 errors.
The headers received in the error response.
The error message.
The response body.
The HTTP status code for the response.
The URL that produced this error message.
Methods
self,
url: str,
headers: Mapping[str, str],
raw_body: Any,
message: str = '',
code: int = 0,
*,
errors: Optional[Dict[str, Dict[str, Any]]] = None
):
View Source
def __init__(self, url, headers, raw_body, message=attr_dict['message'].default, code=attr_dict['code'].default, *, errors=attr_dict['errors'].default): self.url = url self.headers = headers self.raw_body = raw_body self.message = message self.code = code self.status = attr_dict['status'].default self.errors = errors self._cached_str = attr_dict['_cached_str'].default BaseException.__init__(self, self.url,self.headers,self.raw_body,self.message,self.code,self.errors)
Method generated by attrs for class BadRequestError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class BulkDeleteError(HikariError): """Exception raised when a bulk delete fails midway through a call. This will contain the list of message items that failed to be deleted, and will have a cause containing the initial exception. """ messages_deleted: snowflakes.SnowflakeishSequence[messages.PartialMessage] = attr.field() """Any message objects that were deleted before an exception occurred.""" messages_skipped: snowflakes.SnowflakeishSequence[messages.PartialMessage] = attr.field() """Any message objects that were skipped due to an exception.""" @property def percentage_completion(self) -> float: """Return the percentage completion of the bulk delete before it failed.""" deleted = len(self.messages_deleted) total = deleted + len(self.messages_skipped) return 100 * deleted / total def __str__(self) -> str: deleted = len(self.messages_deleted) total = deleted + len(self.messages_skipped) return f"Error encountered when bulk deleting messages ({deleted}/{total} messages deleted)"
Exception raised when a bulk delete fails midway through a call.
This will contain the list of message items that failed to be deleted, and will have a cause containing the initial exception.
Variables and properties
Any message objects that were deleted before an exception occurred.
Any message objects that were skipped due to an exception.
Return the percentage completion of the bulk delete before it failed.
Methods
self,
messages_deleted: Sequence[Union[hikari.messages.PartialMessage, hikari.snowflakes.Snowflake, int]],
messages_skipped: Sequence[Union[hikari.messages.PartialMessage, hikari.snowflakes.Snowflake, int]]
):
View Source
def __init__(self, messages_deleted, messages_skipped): self.messages_deleted = messages_deleted self.messages_skipped = messages_skipped BaseException.__init__(self, self.messages_deleted,self.messages_skipped)
Method generated by attrs for class BulkDeleteError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class ClientHTTPResponseError(HTTPResponseError): """Base exception for an erroneous HTTP response that is a client error. All exceptions derived from this base should be treated as 4xx client errors when encountered. """
Base exception for an erroneous HTTP response that is a client error.
All exceptions derived from this base should be treated as 4xx client errors when encountered.
Variables and properties
The error code.
The headers received in the error response.
The error message.
The response body.
The HTTP status code for the response.
The URL that produced this error message.
Methods
self,
url: str,
status: http.HTTPStatus,
headers: Mapping[str, str],
raw_body: Any,
message: str = '',
code: int = 0
):
View Source
def __init__(self, url, status, headers, raw_body, message=attr_dict['message'].default, code=attr_dict['code'].default): self.url = url self.status = status self.headers = headers self.raw_body = raw_body self.message = message self.code = code BaseException.__init__(self, self.url,self.status,self.headers,self.raw_body,self.message,self.code)
Method generated by attrs for class ClientHTTPResponseError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class ComponentStateConflictError(HikariError): """Exception thrown when an action cannot be executed in the component's current state. Dependent on context this will be thrown for components which are already running or haven't been started yet. """ reason: str = attr.field() """A string to explain the issue.""" def __str__(self) -> str: return self.reason
Exception thrown when an action cannot be executed in the component's current state.
Dependent on context this will be thrown for components which are already running or haven't been started yet.
Variables and properties
A string to explain the issue.
Methods
View Source
def __init__(self, reason): self.reason = reason BaseException.__init__(self, self.reason)
Method generated by attrs for class ComponentStateConflictError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class ForbiddenError(ClientHTTPResponseError): """Raised when you are not allowed to access a specific resource. This means you lack the permissions to do something, either because of permissions set in a guild, or because your application is not whitelisted to use a specific endpoint. """ status: http.HTTPStatus = attr.field(default=http.HTTPStatus.FORBIDDEN, init=False) """The HTTP status code for the response."""
Raised when you are not allowed to access a specific resource.
This means you lack the permissions to do something, either because of permissions set in a guild, or because your application is not whitelisted to use a specific endpoint.
Variables and properties
The error code.
The headers received in the error response.
The error message.
The response body.
The HTTP status code for the response.
The URL that produced this error message.
Methods
self,
url: str,
headers: Mapping[str, str],
raw_body: Any,
message: str = '',
code: int = 0
):
View Source
def __init__(self, url, headers, raw_body, message=attr_dict['message'].default, code=attr_dict['code'].default): self.url = url self.headers = headers self.raw_body = raw_body self.message = message self.code = code self.status = attr_dict['status'].default BaseException.__init__(self, self.url,self.headers,self.raw_body,self.message,self.code)
Method generated by attrs for class ForbiddenError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class GatewayConnectionError(GatewayError): """An exception thrown if a connection issue occurs.""" def __str__(self) -> str: return f"Failed to connect to server: {self.reason!r}"
An exception thrown if a connection issue occurs.
Variables and properties
A string to explain the issue.
Methods
View Source
def __init__(self, reason): self.reason = reason BaseException.__init__(self, self.reason)
Method generated by attrs for class GatewayConnectionError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class GatewayError(HikariError): """A base exception type for anything that can be thrown by the Gateway.""" reason: str = attr.field() """A string to explain the issue.""" def __str__(self) -> str: return self.reason
A base exception type for anything that can be thrown by the Gateway.
Variables and properties
A string to explain the issue.
Methods
View Source
def __init__(self, reason): self.reason = reason BaseException.__init__(self, self.reason)
Method generated by attrs for class GatewayError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class GatewayServerClosedConnectionError(GatewayError): """An exception raised when the server closes the connection.""" code: typing.Union[ShardCloseCode, int, None] = attr.field(default=None) """Return the close code that was received, if there is one. Returns ------- typing.Union[ShardCloseCode, int, None] The shard close code if there was one. Will be a `ShardCloseCode` if the definition is known. Undocumented close codes may instead be an `int` instead. If no close code was received, this will be `None`. """ can_reconnect: bool = attr.field(default=False) """Return `True` if we can recover from this closure. If `True`, it will try to reconnect after this is raised rather than it being propagated to the caller. If `False`, this will be raised, thus stopping the application unless handled explicitly by the user. Returns ------- bool Whether the closure can be recovered from via a reconnect. """ def __str__(self) -> str: return f"Server closed connection with code {self.code} ({self.reason})"
An exception raised when the server closes the connection.
Variables and properties
Return True
if we can recover from this closure.
If True
, it will try to reconnect after this is raised rather than it being propagated to the caller. If False
, this will be raised, thus stopping the application unless handled explicitly by the user.
Returns
- bool: Whether the closure can be recovered from via a reconnect.
Return the close code that was received, if there is one.
Returns
- typing.Union[ShardCloseCode, int, None]: The shard close code if there was one. Will be a
ShardCloseCode
if the definition is known. Undocumented close codes may instead be anint
instead.
If no close code was received, this will be None
.
A string to explain the issue.
Methods
self,
reason: str,
code: Union[hikari.errors.ShardCloseCode, int, NoneType] = None,
can_reconnect: bool = False
):
View Source
def __init__(self, reason, code=attr_dict['code'].default, can_reconnect=attr_dict['can_reconnect'].default): self.reason = reason self.code = code self.can_reconnect = can_reconnect BaseException.__init__(self, self.reason,self.code,self.can_reconnect)
Method generated by attrs for class GatewayServerClosedConnectionError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class HTTPError(HikariError): """Base exception raised if an HTTP error occurs while making a request.""" message: str = attr.field() """The error message."""
Base exception raised if an HTTP error occurs while making a request.
Variables and properties
The error message.
Methods
View Source
def __init__(self, message): self.message = message BaseException.__init__(self, self.message)
Method generated by attrs for class HTTPError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class HTTPResponseError(HTTPError): """Base exception for an erroneous HTTP response.""" url: str = attr.field() """The URL that produced this error message.""" status: http.HTTPStatus = attr.field() """The HTTP status code for the response.""" headers: data_binding.Headers = attr.field() """The headers received in the error response.""" raw_body: typing.Any = attr.field() """The response body.""" message: str = attr.field(default="") """The error message.""" code: int = attr.field(default=0) """The error code.""" def __str__(self) -> str: name = self.status.name.replace("_", " ").title() name_value = f"{name} {self.status.value}" if self.code: code_str = f" ({self.code})" else: code_str = "" if self.message: body = self.message else: try: body = self.raw_body.decode("utf-8") except (AttributeError, UnicodeDecodeError, TypeError, ValueError): body = str(self.raw_body) chomped = len(body) > 200 return f"{name_value}:{code_str} '{body[:200]}{'...' if chomped else ''}' for {self.url}"
Base exception for an erroneous HTTP response.
Variables and properties
The error code.
The headers received in the error response.
The error message.
The response body.
The HTTP status code for the response.
The URL that produced this error message.
Methods
self,
url: str,
status: http.HTTPStatus,
headers: Mapping[str, str],
raw_body: Any,
message: str = '',
code: int = 0
):
View Source
def __init__(self, url, status, headers, raw_body, message=attr_dict['message'].default, code=attr_dict['code'].default): self.url = url self.status = status self.headers = headers self.raw_body = raw_body self.message = message self.code = code BaseException.__init__(self, self.url,self.status,self.headers,self.raw_body,self.message,self.code)
Method generated by attrs for class HTTPResponseError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr_extensions.with_copy @attr.define(auto_exc=True, repr=False, init=False, slots=False) class HikariError(RuntimeError): """Base for an error raised by this API. Any exceptions should derive from this. .. note:: You should never initialize this exception directly. """
Base for an error raised by this API.
Any exceptions should derive from this.
Note: You should never initialize this exception directly.
Variables and properties
Methods
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class HikariInterrupt(KeyboardInterrupt, HikariError): """Exception raised when a kill signal is handled internally.""" signum: int = attr.field() """The signal number that was raised.""" signame: str = attr.field() """The signal name that was raised."""
Exception raised when a kill signal is handled internally.
Variables and properties
The signal name that was raised.
The signal number that was raised.
Methods
View Source
def __init__(self, signum, signame): self.signum = signum self.signame = signame BaseException.__init__(self, self.signum,self.signame)
Method generated by attrs for class HikariInterrupt.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr_extensions.with_copy @attr.define(auto_exc=True, repr=False, init=False, slots=False) class HikariWarning(RuntimeWarning): """Base for a warning raised by this API. Any warnings should derive from this. .. note:: You should never initialize this warning directly. """
Base for a warning raised by this API.
Any warnings should derive from this.
Note: You should never initialize this warning directly.
Variables and properties
Methods
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class InternalServerError(HTTPResponseError): """Base exception for an erroneous HTTP response that is a server error. All exceptions derived from this base should be treated as 5xx server errors when encountered. If you get one of these, it is not your fault! """
Base exception for an erroneous HTTP response that is a server error.
All exceptions derived from this base should be treated as 5xx server errors when encountered. If you get one of these, it is not your fault!
Variables and properties
The error code.
The headers received in the error response.
The error message.
The response body.
The HTTP status code for the response.
The URL that produced this error message.
Methods
self,
url: str,
status: http.HTTPStatus,
headers: Mapping[str, str],
raw_body: Any,
message: str = '',
code: int = 0
):
View Source
def __init__(self, url, status, headers, raw_body, message=attr_dict['message'].default, code=attr_dict['code'].default): self.url = url self.status = status self.headers = headers self.raw_body = raw_body self.message = message self.code = code BaseException.__init__(self, self.url,self.status,self.headers,self.raw_body,self.message,self.code)
Method generated by attrs for class InternalServerError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class MissingIntentError(HikariError, ValueError): """Error raised when you try to perform an action without an intent. This is usually raised when querying the cache for something that is unavailable due to certain intents being disabled. """ intents: intents_.Intents = attr.field() """The combination of intents that are missing.""" def __str__(self) -> str: return "You are missing the following intent(s): " + ", ".join(map(str, self.intents.split()))
Error raised when you try to perform an action without an intent.
This is usually raised when querying the cache for something that is unavailable due to certain intents being disabled.
Variables and properties
The combination of intents that are missing.
Methods
View Source
def __init__(self, intents): self.intents = intents BaseException.__init__(self, self.intents)
Method generated by attrs for class MissingIntentError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, init=False, slots=False) class MissingIntentWarning(HikariWarning): """Warning raised when subscribing to an event that cannot be fired. This is caused by your application missing certain intents. """
Warning raised when subscribing to an event that cannot be fired.
This is caused by your application missing certain intents.
Variables and properties
Methods
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class NotFoundError(ClientHTTPResponseError): """Raised when something is not found.""" status: http.HTTPStatus = attr.field(default=http.HTTPStatus.NOT_FOUND, init=False) """The HTTP status code for the response."""
Raised when something is not found.
Variables and properties
The error code.
The headers received in the error response.
The error message.
The response body.
The HTTP status code for the response.
The URL that produced this error message.
Methods
self,
url: str,
headers: Mapping[str, str],
raw_body: Any,
message: str = '',
code: int = 0
):
View Source
def __init__(self, url, headers, raw_body, message=attr_dict['message'].default, code=attr_dict['code'].default): self.url = url self.headers = headers self.raw_body = raw_body self.message = message self.code = code self.status = attr_dict['status'].default BaseException.__init__(self, self.url,self.headers,self.raw_body,self.message,self.code)
Method generated by attrs for class NotFoundError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, kw_only=True, repr=False, slots=False) class RateLimitTooLongError(HTTPError): """Internal error raised if the wait for a rate limit is too long. This is similar to `asyncio.TimeoutError` in the way that it is used, but this will be raised pre-emptively and immediately if the period of time needed to wait is greater than a user-defined limit. This will almost always be route-specific. If you receive this, it is unlikely that performing the same call for a different channel/guild/user will also have this rate limit. """ route: routes.CompiledRoute = attr.field() """The route that produced this error.""" retry_after: float = attr.field() """How many seconds to wait before you can retry this specific request.""" max_retry_after: float = attr.field() """How long the client is allowed to wait for at a maximum before raising.""" reset_at: float = attr.field() """UNIX timestamp of when this limit will be lifted.""" limit: int = attr.field() """The maximum number of calls per window for this rate limit.""" period: float = attr.field() """How long the rate limit window lasts for from start to end.""" message: str = attr.field(init=False) """The error message.""" @message.default def _(self) -> str: return ( "The request has been rejected, as you would be waiting for more than" f"the max retry-after ({self.max_retry_after}) on route {self.route}" ) # This may support other types of limits in the future, this currently # exists to be self-documenting to the user and for future compatibility # only. @property def remaining(self) -> typing.Literal[0]: """Remaining requests in this window. This will always be `0` symbolically. """ return 0 def __str__(self) -> str: return self.message
Internal error raised if the wait for a rate limit is too long.
This is similar to asyncio.TimeoutError
in the way that it is used, but this will be raised pre-emptively and immediately if the period of time needed to wait is greater than a user-defined limit.
This will almost always be route-specific. If you receive this, it is unlikely that performing the same call for a different channel/guild/user will also have this rate limit.
Variables and properties
The maximum number of calls per window for this rate limit.
How long the client is allowed to wait for at a maximum before raising.
The error message.
How long the rate limit window lasts for from start to end.
Remaining requests in this window.
This will always be 0
symbolically.
UNIX timestamp of when this limit will be lifted.
How many seconds to wait before you can retry this specific request.
The route that produced this error.
Methods
self,
*,
route: hikari.internal.routes.CompiledRoute,
retry_after: float,
max_retry_after: float,
reset_at: float,
limit: int,
period: float
):
View Source
def __init__(self, *, route, retry_after, max_retry_after, reset_at, limit, period): self.route = route self.retry_after = retry_after self.max_retry_after = max_retry_after self.reset_at = reset_at self.limit = limit self.period = period self.message = __attr_factory_message(self) BaseException.__init__(self, self.route,self.retry_after,self.max_retry_after,self.reset_at,self.limit,self.period)
Method generated by attrs for class RateLimitTooLongError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, kw_only=True, repr=False, slots=False) class RateLimitedError(ClientHTTPResponseError): """Raised when a non-global rate limit that cannot be handled occurs. If you receive one of these, you should NOT try again until the given time has passed, either discarding the operation you performed, or waiting until the given time has passed first. Note that it may still be valid to send requests with different attributes in them. A use case for this by Discord appears to be to stop abuse from bots that change channel names, etc, regularly. This kind of action allegedly causes a fair amount of overhead internally for Discord. In the case you encounter this, you may be able to send different requests that manipulate the same entities (in this case editing the same channel) that do not use the same collection of attributes as the previous request. """ route: routes.CompiledRoute = attr.field() """The route that produced this error.""" retry_after: float = attr.field() """How many seconds to wait before you can reuse the route with the specific request.""" status: http.HTTPStatus = attr.field(default=http.HTTPStatus.TOO_MANY_REQUESTS, init=False) """The HTTP status code for the response.""" message: str = attr.field(init=False) """The error message.""" @message.default def _(self) -> str: return f"You are being rate-limited for {self.retry_after:,} seconds on route {self.route}. Please slow down!"
Raised when a non-global rate limit that cannot be handled occurs.
If you receive one of these, you should NOT try again until the given time has passed, either discarding the operation you performed, or waiting until the given time has passed first. Note that it may still be valid to send requests with different attributes in them.
A use case for this by Discord appears to be to stop abuse from bots that change channel names, etc, regularly. This kind of action allegedly causes a fair amount of overhead internally for Discord. In the case you encounter this, you may be able to send different requests that manipulate the same entities (in this case editing the same channel) that do not use the same collection of attributes as the previous request.
Variables and properties
The error code.
The headers received in the error response.
The error message.
The response body.
How many seconds to wait before you can reuse the route with the specific request.
The route that produced this error.
The HTTP status code for the response.
The URL that produced this error message.
Methods
self,
*,
url: str,
headers: Mapping[str, str],
raw_body: Any,
code: int = 0,
route: hikari.internal.routes.CompiledRoute,
retry_after: float
):
View Source
def __init__(self, *, url, headers, raw_body, code=attr_dict['code'].default, route, retry_after): self.url = url self.headers = headers self.raw_body = raw_body self.code = code self.route = route self.retry_after = retry_after self.status = attr_dict['status'].default self.message = __attr_factory_message(self) BaseException.__init__(self, self.url,self.headers,self.raw_body,self.code,self.route,self.retry_after)
Method generated by attrs for class RateLimitedError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@typing.final class ShardCloseCode(int, enums.Enum): """Reasons for a shard connection closure.""" NORMAL_CLOSURE = 1_000 GOING_AWAY = 1_001 PROTOCOL_ERROR = 1_002 TYPE_ERROR = 1_003 ENCODING_ERROR = 1_007 POLICY_VIOLATION = 1_008 TOO_BIG = 1_009 UNEXPECTED_CONDITION = 1_011 UNKNOWN_ERROR = 4_000 UNKNOWN_OPCODE = 4_001 DECODE_ERROR = 4_002 NOT_AUTHENTICATED = 4_003 AUTHENTICATION_FAILED = 4_004 ALREADY_AUTHENTICATED = 4_005 INVALID_SEQ = 4_007 RATE_LIMITED = 4_008 SESSION_TIMEOUT = 4_009 INVALID_SHARD = 4_010 SHARDING_REQUIRED = 4_011 INVALID_VERSION = 4_012 INVALID_INTENT = 4_013 DISALLOWED_INTENT = 4_014 @property def is_standard(self) -> bool: """Return `True` if this is a standard code.""" return (self.value // 1000) == 1
Reasons for a shard connection closure.
Variables and properties
the denominator of a rational number in lowest terms
the imaginary part of a complex number
Return True
if this is a standard code.
Return the name of the enum member as a str
.
the numerator of a rational number in lowest terms
the real part of a complex number
Return the value of the enum member.
Methods
View Source
def __call__(cls, value: typing.Any) -> typing.Any: """Cast a value to the enum, returning the raw value that was passed if value not found.""" try: return cls._value_to_member_map_[value] except KeyError: # If we can't find the value, just return what got casted in return value
Cast a value to the enum, returning the raw value that was passed if value not found.
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
Number of bits necessary to represent self in binary.
>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
Returns self, the complex conjugate of any int.
Return the integer represented by the given array of bytes.
bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Indicates whether two's complement is used to represent the integer.
Return an array of bytes representing an integer.
length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
View Source
@attr.define(auto_exc=True, repr=False, slots=False) class UnrecognisedEntityError(HikariError): """An exception thrown when an unrecognised entity is found.""" reason: str = attr.field() """A string to explain the issue.""" def __str__(self) -> str: return self.reason
An exception thrown when an unrecognised entity is found.
Variables and properties
A string to explain the issue.
Methods
View Source
def __init__(self, reason): self.reason = reason BaseException.__init__(self, self.reason)
Method generated by attrs for class UnrecognisedEntityError.
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.
View Source
@attr.define(auto_exc=True, repr=False, init=False, slots=False) class VoiceError(HikariError): """Error raised when a problem occurs with the voice subsystem."""
Error raised when a problem occurs with the voice subsystem.
Variables and properties
Methods
Exception.with_traceback(tb) -- set self.__traceback__ to tb and return self.