Source code for redditwarp.http.exceptions
from __future__ import annotations
from typing import Mapping, ClassVar
from http import HTTPStatus
from ..exceptions import ArgExcMixin
[docs]class TimeoutException(ArgExc):
"""A timeout exception class to wrap timeout errors from HTTP transport libraries."""
[docs]class StatusCodeException(ArgExc):
"""An exception class representing HTTP status codes as errors."""
__match_args__ = ('status_code',)
STATUS_CODE: ClassVar[int] = 0
def __init__(self, arg: object = None, *, status_code: int) -> None:
super().__init__(arg)
self.status_code: int = status_code
("")
[docs] def get_default_message(self) -> str:
sts = self.status_code
try:
return f"{sts} {HTTPStatus(sts).phrase}"
except ValueError:
return f"{sts}"
[docs]class StatusCodeExceptionTypes:
[docs] class InformationalStatusCodeException(StatusCodeException):
STATUS_CODE: ClassVar[int] = -100
status_code_exception_class_by_status_code: Mapping[int, type[StatusCodeException]] = {
cls.STATUS_CODE: cls
for cls in [
# Client errors
StatusCodeExceptionTypes.BadRequest,
StatusCodeExceptionTypes.Unauthorized,
StatusCodeExceptionTypes.Forbidden,
StatusCodeExceptionTypes.NotFound,
StatusCodeExceptionTypes.Conflict,
StatusCodeExceptionTypes.PayloadTooLarge,
StatusCodeExceptionTypes.URITooLong,
StatusCodeExceptionTypes.TooManyRequests,
# Server errors
StatusCodeExceptionTypes.InternalServerError,
StatusCodeExceptionTypes.BadGateway,
StatusCodeExceptionTypes.ServiceUnavailable,
StatusCodeExceptionTypes.GatewayTimeout,
]
}
[docs]def get_status_code_exception_class_by_status_code(n: int) -> type[StatusCodeException]:
klass = status_code_exception_class_by_status_code.get(n)
if klass is None:
klass = StatusCodeException
if 100 <= n <= 199:
klass = StatusCodeExceptionTypes.InformationalStatusCodeException
elif 200 <= n <= 299:
klass = StatusCodeExceptionTypes.SuccessfulStatusCodeException
elif 300 <= n <= 399:
klass = StatusCodeExceptionTypes.RedirectionStatusCodeException
elif 400 <= n <= 499:
klass = StatusCodeExceptionTypes.ClientErrorStatusCodeException
elif 500 <= n <= 599:
klass = StatusCodeExceptionTypes.ServerErrorStatusCodeException
return klass
[docs]def is_successful_status(n: int) -> bool:
"""Return true if `200 <= n < 300`."""
return 200 <= n <= 299
[docs]def raise_now(n: int) -> None:
"""Raises a :class:`.StatusCodeException` exception type based on the given HTTP status number."""
raise get_status_code_exception_class_by_status_code(n)(status_code=n)
[docs]def ensure_successful_status(n: int) -> None:
"""Raises a :class:`.StatusCodeException` exception if `is_successful_status(n)` returns false."""
if not is_successful_status(n):
raise_now(n)