diff --git a/hondana/errors.py b/hondana/errors.py index 42472e5..52feecd 100644 --- a/hondana/errors.py +++ b/hondana/errors.py @@ -29,10 +29,13 @@ if TYPE_CHECKING: import aiohttp + from hondana.types_.token import GetTokenPayload + from .types_.errors import ErrorType __all__ = ( "AuthenticationRequired", + "RefreshTokenFailure", "UploadInProgress", "MangaDexServerError", "APIException", @@ -83,6 +86,14 @@ class AuthenticationRequired(Exception): """An exception to be raised when authentication is required to use this endpoint.""" +class RefreshTokenFailure(Exception): + """An exception to be raised when trying to use or access the refresh token fails.""" + + def __init__(self, message: str, response_data: GetTokenPayload | None = None) -> None: + self.message = message + self.data = response_data + + class UploadInProgress(Exception): """An exception to be raised when an upload in progress is already found for the logged-in user. diff --git a/hondana/http.py b/hondana/http.py index 438c2f1..5ef8554 100755 --- a/hondana/http.py +++ b/hondana/http.py @@ -49,7 +49,7 @@ ReportReason, ReportStatus, ) -from .errors import APIException, BadRequest, Forbidden, MangaDexServerError, NotFound, Unauthorized +from .errors import APIException, BadRequest, Forbidden, MangaDexServerError, NotFound, RefreshTokenFailure, Unauthorized from .utils import ( MANGA_TAGS, MANGADEX_TIME_REGEX, @@ -209,7 +209,10 @@ async def refresh(self) -> Self: async with self._http.request(route.verb, route.url, data=data) as resp: response_data: token.GetTokenPayload = await resp.json() - self.raw_token = response_data["access_token"] + try: + self.raw_token = response_data["access_token"] + except KeyError as exc: + raise RefreshTokenFailure("Could not access refresh token in the auth payload", response_data) from exc self._parse() @@ -329,7 +332,14 @@ async def get_token(self) -> Token: and self._auth_token.has_expired() and (self._auth_token.refresh_token and not self._auth_token.refresh_token.has_expired()) ): - return await self._auth_token.refresh() + try: + await self._auth_token.refresh() + except RefreshTokenFailure as exc: + LOGGER.error( + "Failed to refresh token. Will attempt the login flow again. Errored payload:\n%s", + exc.data, + exc_info=exc, + ) route = AuthRoute("POST", "/token")