Improve the type hints of synapse.api.errors. (#7820)

This commit is contained in:
Patrick Cloke 2020-07-14 07:03:58 -04:00 committed by GitHub
parent 93c8b077ed
commit 4db1509516
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 55 deletions

1
changelog.d/7820.misc Normal file
View File

@ -0,0 +1 @@
Add type hints to synapse.api.errors module.

View File

@ -17,11 +17,15 @@
"""Contains exceptions and error codes.""" """Contains exceptions and error codes."""
import json import json
import logging import logging
import typing
from http import HTTPStatus from http import HTTPStatus
from typing import Dict, List from typing import Dict, List, Optional, Union
from twisted.web import http from twisted.web import http
if typing.TYPE_CHECKING:
from synapse.types import JsonDict
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -76,11 +80,11 @@ class CodeMessageException(RuntimeError):
"""An exception with integer code and message string attributes. """An exception with integer code and message string attributes.
Attributes: Attributes:
code (int): HTTP error code code: HTTP error code
msg (str): string describing the error msg: string describing the error
""" """
def __init__(self, code, msg): def __init__(self, code: Union[int, HTTPStatus], msg: str):
super(CodeMessageException, self).__init__("%d: %s" % (code, msg)) super(CodeMessageException, self).__init__("%d: %s" % (code, msg))
# Some calls to this method pass instances of http.HTTPStatus for `code`. # Some calls to this method pass instances of http.HTTPStatus for `code`.
@ -121,16 +125,16 @@ class SynapseError(CodeMessageException):
message (as well as an HTTP status code). message (as well as an HTTP status code).
Attributes: Attributes:
errcode (str): Matrix error code e.g 'M_FORBIDDEN' errcode: Matrix error code e.g 'M_FORBIDDEN'
""" """
def __init__(self, code, msg, errcode=Codes.UNKNOWN): def __init__(self, code: int, msg: str, errcode: str = Codes.UNKNOWN):
"""Constructs a synapse error. """Constructs a synapse error.
Args: Args:
code (int): The integer error code (an HTTP response code) code: The integer error code (an HTTP response code)
msg (str): The human-readable error message. msg: The human-readable error message.
errcode (str): The matrix error code e.g 'M_FORBIDDEN' errcode: The matrix error code e.g 'M_FORBIDDEN'
""" """
super(SynapseError, self).__init__(code, msg) super(SynapseError, self).__init__(code, msg)
self.errcode = errcode self.errcode = errcode
@ -143,10 +147,16 @@ class ProxiedRequestError(SynapseError):
"""An error from a general matrix endpoint, eg. from a proxied Matrix API call. """An error from a general matrix endpoint, eg. from a proxied Matrix API call.
Attributes: Attributes:
errcode (str): Matrix error code e.g 'M_FORBIDDEN' errcode: Matrix error code e.g 'M_FORBIDDEN'
""" """
def __init__(self, code, msg, errcode=Codes.UNKNOWN, additional_fields=None): def __init__(
self,
code: int,
msg: str,
errcode: str = Codes.UNKNOWN,
additional_fields: Optional[Dict] = None,
):
super(ProxiedRequestError, self).__init__(code, msg, errcode) super(ProxiedRequestError, self).__init__(code, msg, errcode)
if additional_fields is None: if additional_fields is None:
self._additional_fields = {} # type: Dict self._additional_fields = {} # type: Dict
@ -162,12 +172,12 @@ class ConsentNotGivenError(SynapseError):
privacy policy. privacy policy.
""" """
def __init__(self, msg, consent_uri): def __init__(self, msg: str, consent_uri: str):
"""Constructs a ConsentNotGivenError """Constructs a ConsentNotGivenError
Args: Args:
msg (str): The human-readable error message msg: The human-readable error message
consent_url (str): The URL where the user can give their consent consent_url: The URL where the user can give their consent
""" """
super(ConsentNotGivenError, self).__init__( super(ConsentNotGivenError, self).__init__(
code=HTTPStatus.FORBIDDEN, msg=msg, errcode=Codes.CONSENT_NOT_GIVEN code=HTTPStatus.FORBIDDEN, msg=msg, errcode=Codes.CONSENT_NOT_GIVEN
@ -183,11 +193,11 @@ class UserDeactivatedError(SynapseError):
authenticated endpoint, but the account has been deactivated. authenticated endpoint, but the account has been deactivated.
""" """
def __init__(self, msg): def __init__(self, msg: str):
"""Constructs a UserDeactivatedError """Constructs a UserDeactivatedError
Args: Args:
msg (str): The human-readable error message msg: The human-readable error message
""" """
super(UserDeactivatedError, self).__init__( super(UserDeactivatedError, self).__init__(
code=HTTPStatus.FORBIDDEN, msg=msg, errcode=Codes.USER_DEACTIVATED code=HTTPStatus.FORBIDDEN, msg=msg, errcode=Codes.USER_DEACTIVATED
@ -199,16 +209,16 @@ class FederationDeniedError(SynapseError):
is not on its federation whitelist. is not on its federation whitelist.
Attributes: Attributes:
destination (str): The destination which has been denied destination: The destination which has been denied
""" """
def __init__(self, destination): def __init__(self, destination: Optional[str]):
"""Raised by federation client or server to indicate that we are """Raised by federation client or server to indicate that we are
are deliberately not attempting to contact a given server because it is are deliberately not attempting to contact a given server because it is
not on our federation whitelist. not on our federation whitelist.
Args: Args:
destination (str): the domain in question destination: the domain in question
""" """
self.destination = destination self.destination = destination
@ -226,11 +236,11 @@ class InteractiveAuthIncompleteError(Exception):
(This indicates we should return a 401 with 'result' as the body) (This indicates we should return a 401 with 'result' as the body)
Attributes: Attributes:
result (dict): the server response to the request, which should be result: the server response to the request, which should be
passed back to the client passed back to the client
""" """
def __init__(self, result): def __init__(self, result: "JsonDict"):
super(InteractiveAuthIncompleteError, self).__init__( super(InteractiveAuthIncompleteError, self).__init__(
"Interactive auth not yet complete" "Interactive auth not yet complete"
) )
@ -243,7 +253,6 @@ class UnrecognizedRequestError(SynapseError):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
if "errcode" not in kwargs: if "errcode" not in kwargs:
kwargs["errcode"] = Codes.UNRECOGNIZED kwargs["errcode"] = Codes.UNRECOGNIZED
message = None
if len(args) == 0: if len(args) == 0:
message = "Unrecognized request" message = "Unrecognized request"
else: else:
@ -254,7 +263,7 @@ class UnrecognizedRequestError(SynapseError):
class NotFoundError(SynapseError): class NotFoundError(SynapseError):
"""An error indicating we can't find the thing you asked for""" """An error indicating we can't find the thing you asked for"""
def __init__(self, msg="Not found", errcode=Codes.NOT_FOUND): def __init__(self, msg: str = "Not found", errcode: str = Codes.NOT_FOUND):
super(NotFoundError, self).__init__(404, msg, errcode=errcode) super(NotFoundError, self).__init__(404, msg, errcode=errcode)
@ -280,21 +289,23 @@ class InvalidClientCredentialsError(SynapseError):
M_UNKNOWN_TOKEN respectively. M_UNKNOWN_TOKEN respectively.
""" """
def __init__(self, msg, errcode): def __init__(self, msg: str, errcode: str):
super().__init__(code=401, msg=msg, errcode=errcode) super().__init__(code=401, msg=msg, errcode=errcode)
class MissingClientTokenError(InvalidClientCredentialsError): class MissingClientTokenError(InvalidClientCredentialsError):
"""Raised when we couldn't find the access token in a request""" """Raised when we couldn't find the access token in a request"""
def __init__(self, msg="Missing access token"): def __init__(self, msg: str = "Missing access token"):
super().__init__(msg=msg, errcode="M_MISSING_TOKEN") super().__init__(msg=msg, errcode="M_MISSING_TOKEN")
class InvalidClientTokenError(InvalidClientCredentialsError): class InvalidClientTokenError(InvalidClientCredentialsError):
"""Raised when we didn't understand the access token in a request""" """Raised when we didn't understand the access token in a request"""
def __init__(self, msg="Unrecognised access token", soft_logout=False): def __init__(
self, msg: str = "Unrecognised access token", soft_logout: bool = False
):
super().__init__(msg=msg, errcode="M_UNKNOWN_TOKEN") super().__init__(msg=msg, errcode="M_UNKNOWN_TOKEN")
self._soft_logout = soft_logout self._soft_logout = soft_logout
@ -312,11 +323,11 @@ class ResourceLimitError(SynapseError):
def __init__( def __init__(
self, self,
code, code: int,
msg, msg: str,
errcode=Codes.RESOURCE_LIMIT_EXCEEDED, errcode: str = Codes.RESOURCE_LIMIT_EXCEEDED,
admin_contact=None, admin_contact: Optional[str] = None,
limit_type=None, limit_type: Optional[str] = None,
): ):
self.admin_contact = admin_contact self.admin_contact = admin_contact
self.limit_type = limit_type self.limit_type = limit_type
@ -364,10 +375,10 @@ class StoreError(SynapseError):
class InvalidCaptchaError(SynapseError): class InvalidCaptchaError(SynapseError):
def __init__( def __init__(
self, self,
code=400, code: int = 400,
msg="Invalid captcha.", msg: str = "Invalid captcha.",
error_url=None, error_url: Optional[str] = None,
errcode=Codes.CAPTCHA_INVALID, errcode: str = Codes.CAPTCHA_INVALID,
): ):
super(InvalidCaptchaError, self).__init__(code, msg, errcode) super(InvalidCaptchaError, self).__init__(code, msg, errcode)
self.error_url = error_url self.error_url = error_url
@ -382,10 +393,10 @@ class LimitExceededError(SynapseError):
def __init__( def __init__(
self, self,
code=429, code: int = 429,
msg="Too Many Requests", msg: str = "Too Many Requests",
retry_after_ms=None, retry_after_ms: Optional[int] = None,
errcode=Codes.LIMIT_EXCEEDED, errcode: str = Codes.LIMIT_EXCEEDED,
): ):
super(LimitExceededError, self).__init__(code, msg, errcode) super(LimitExceededError, self).__init__(code, msg, errcode)
self.retry_after_ms = retry_after_ms self.retry_after_ms = retry_after_ms
@ -398,10 +409,10 @@ class RoomKeysVersionError(SynapseError):
"""A client has tried to upload to a non-current version of the room_keys store """A client has tried to upload to a non-current version of the room_keys store
""" """
def __init__(self, current_version): def __init__(self, current_version: str):
""" """
Args: Args:
current_version (str): the current version of the store they should have used current_version: the current version of the store they should have used
""" """
super(RoomKeysVersionError, self).__init__( super(RoomKeysVersionError, self).__init__(
403, "Wrong room_keys version", Codes.WRONG_ROOM_KEYS_VERSION 403, "Wrong room_keys version", Codes.WRONG_ROOM_KEYS_VERSION
@ -413,7 +424,7 @@ class UnsupportedRoomVersionError(SynapseError):
"""The client's request to create a room used a room version that the server does """The client's request to create a room used a room version that the server does
not support.""" not support."""
def __init__(self, msg="Homeserver does not support this room version"): def __init__(self, msg: str = "Homeserver does not support this room version"):
super(UnsupportedRoomVersionError, self).__init__( super(UnsupportedRoomVersionError, self).__init__(
code=400, msg=msg, errcode=Codes.UNSUPPORTED_ROOM_VERSION, code=400, msg=msg, errcode=Codes.UNSUPPORTED_ROOM_VERSION,
) )
@ -435,7 +446,7 @@ class IncompatibleRoomVersionError(SynapseError):
failing. failing.
""" """
def __init__(self, room_version): def __init__(self, room_version: str):
super(IncompatibleRoomVersionError, self).__init__( super(IncompatibleRoomVersionError, self).__init__(
code=400, code=400,
msg="Your homeserver does not support the features required to " msg="Your homeserver does not support the features required to "
@ -455,8 +466,8 @@ class PasswordRefusedError(SynapseError):
def __init__( def __init__(
self, self,
msg="This password doesn't comply with the server's policy", msg: str = "This password doesn't comply with the server's policy",
errcode=Codes.WEAK_PASSWORD, errcode: str = Codes.WEAK_PASSWORD,
): ):
super(PasswordRefusedError, self).__init__( super(PasswordRefusedError, self).__init__(
code=400, msg=msg, errcode=errcode, code=400, msg=msg, errcode=errcode,
@ -481,14 +492,14 @@ class RequestSendFailed(RuntimeError):
self.can_retry = can_retry self.can_retry = can_retry
def cs_error(msg, code=Codes.UNKNOWN, **kwargs): def cs_error(msg: str, code: str = Codes.UNKNOWN, **kwargs):
""" Utility method for constructing an error response for client-server """ Utility method for constructing an error response for client-server
interactions. interactions.
Args: Args:
msg (str): The error message. msg: The error message.
code (str): The error code. code: The error code.
kwargs : Additional keys to add to the response. kwargs: Additional keys to add to the response.
Returns: Returns:
A dict representing the error response JSON. A dict representing the error response JSON.
""" """
@ -510,7 +521,14 @@ class FederationError(RuntimeError):
is wrong (e.g., it referred to an invalid event) is wrong (e.g., it referred to an invalid event)
""" """
def __init__(self, level, code, reason, affected, source=None): def __init__(
self,
level: str,
code: int,
reason: str,
affected: str,
source: Optional[str] = None,
):
if level not in ["FATAL", "ERROR", "WARN"]: if level not in ["FATAL", "ERROR", "WARN"]:
raise ValueError("Level is not valid: %s" % (level,)) raise ValueError("Level is not valid: %s" % (level,))
self.level = level self.level = level
@ -537,16 +555,16 @@ class HttpResponseException(CodeMessageException):
Represents an HTTP-level failure of an outbound request Represents an HTTP-level failure of an outbound request
Attributes: Attributes:
response (bytes): body of response response: body of response
""" """
def __init__(self, code, msg, response): def __init__(self, code: int, msg: str, response: bytes):
""" """
Args: Args:
code (int): HTTP status code code: HTTP status code
msg (str): reason phrase from HTTP response status line msg: reason phrase from HTTP response status line
response (bytes): body of response response: body of response
""" """
super(HttpResponseException, self).__init__(code, msg) super(HttpResponseException, self).__init__(code, msg)
self.response = response self.response = response