feat(auth): send a request again when its token lapsed in the queue
A request can wait to be served for longer than the access token it was sent with lives, and comes back refused for a token that was valid when it left. Uploads that take minutes make that wait ordinary. - tell an expired token apart from any other refusal by the code the API returns, and retry only that one, once - prefer a token another process left behind over minting a second: it saves a round trip, and a rotating provider would retire one that is still in use. Assign it rather than read it, since the setter is what rewrites the session header the retry will carry - settle the token before the request so the one compared afterwards is the one that was actually sent - report an overloaded server when the second attempt is refused too, and let API errors out of the upload path with their own type
This commit is contained in:
+12
-1
@@ -5,7 +5,13 @@ from pydantic import TypeAdapter
|
||||
from requests import Response
|
||||
|
||||
from mdrsclient.connection import MDRSConnection
|
||||
from mdrsclient.exceptions import BadRequestException, ForbiddenException, UnauthorizedException, UnexpectedException
|
||||
from mdrsclient.exceptions import (
|
||||
BadRequestException,
|
||||
ForbiddenException,
|
||||
TokenExpiredException,
|
||||
UnauthorizedException,
|
||||
UnexpectedException,
|
||||
)
|
||||
from mdrsclient.models.error import DRFStandardizedErrors
|
||||
|
||||
|
||||
@@ -23,6 +29,11 @@ class BaseApi(ABC):
|
||||
if response.status_code == requests.codes.bad_request:
|
||||
raise BadRequestException(errors.errors[0].detail)
|
||||
elif response.status_code == requests.codes.unauthorized:
|
||||
# A request can wait in the server's queue for longer than the access
|
||||
# token it was sent with lives, so an expired token here does not mean
|
||||
# the session is over - it means this one request arrived too late.
|
||||
if any(e.code == "token_not_valid" for e in errors.errors):
|
||||
raise TokenExpiredException("Access token expired before the request was served.")
|
||||
raise UnauthorizedException("Login required.")
|
||||
elif response.status_code == requests.codes.forbidden:
|
||||
raise ForbiddenException("You do not have enough permissions. Access is denied.")
|
||||
|
||||
Reference in New Issue
Block a user