Skip to content

Commit

Permalink
Clear cookies after any 403 (forbidden/login) error
Browse files Browse the repository at this point in the history
Reduce 403 retry delay from 15 to 5 minutes.
Retry 403 errors immediately a few times after any request other than Circles.
  • Loading branch information
pnbruckner committed May 20, 2024
1 parent 01de2a5 commit ed42c71
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
3 changes: 2 additions & 1 deletion custom_components/life360/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
ATTRIBUTION = "Data provided by life360.com"
COMM_MAX_RETRIES = 4
COMM_TIMEOUT = ClientTimeout(sock_connect=15, total=60)
LOGIN_ERROR_RETRY_DELAY = 15 * 60
LOGIN_ERROR_RETRY_DELAY = 5 * 60
MAX_LOGIN_ERROR_RETRIES = 2
SPEED_FACTOR_MPH = 2.25
SPEED_DIGITS = 1
UPDATE_INTERVAL = timedelta(seconds=5)
Expand Down
37 changes: 26 additions & 11 deletions custom_components/life360/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
COMM_TIMEOUT,
DOMAIN,
LOGIN_ERROR_RETRY_DELAY,
MAX_LOGIN_ERROR_RETRIES,
SIGNAL_ACCT_STATUS,
UPDATE_INTERVAL,
)
Expand Down Expand Up @@ -62,12 +63,12 @@ class AccountData:
online: bool = True


class LoginRateLimitErrorResp(Enum):
class LoginRateLimitErrResp(Enum):
"""Response to Login or RateLimited errors."""

ERROR = auto()
SILENT = auto()
LTD_LOGIN_ERROR_RETRY = auto()
RETRY = auto()
SILENT = auto()


class RequestError(Enum):
Expand Down Expand Up @@ -315,7 +316,7 @@ async def _get_raw_circles_list(
) -> list[list[dict[str, str]] | RequestError]:
"""Get raw Circle data for each Circle that can be seen by each account."""
lrle_resp = (
LoginRateLimitErrorResp.RETRY if retry else LoginRateLimitErrorResp.SILENT
LoginRateLimitErrResp.RETRY if retry else LoginRateLimitErrResp.SILENT
)
return await asyncio.gather( # type: ignore[no-any-return]
*(
Expand Down Expand Up @@ -406,13 +407,14 @@ async def _request(
target: Callable[[*_Ts], Coroutine[Any, Any, _R]],
*args: *_Ts,
msg: str,
lrle_resp: LoginRateLimitErrorResp = LoginRateLimitErrorResp.ERROR,
lrle_resp: LoginRateLimitErrResp = LoginRateLimitErrResp.LTD_LOGIN_ERROR_RETRY,
) -> _R | RequestError:
"""Make a request to the Life360 server."""
if self._acct_data[aid].failed.is_set():
return RequestError.NO_DATA

start = dt_util.now()
login_error_retries = 0
delay: int | None = None
delay_reason = ""
warned = False
Expand Down Expand Up @@ -464,35 +466,48 @@ async def _request(
request_task = None
self._set_acct_exc(aid)
return result

except NotModified:
self._set_acct_exc(aid)
return RequestError.NOT_MODIFIED

except LoginError as exc:
if lrle_resp is LoginRateLimitErrorResp.RETRY:
self._acct_data[aid].session.cookie_jar.clear()
self._acct_data[aid].session.cookie_jar.clear()

if (
lrle_resp is LoginRateLimitErrResp.RETRY
or lrle_resp is LoginRateLimitErrResp.LTD_LOGIN_ERROR_RETRY
and login_error_retries < MAX_LOGIN_ERROR_RETRIES
):
self._set_acct_exc(aid)
delay = LOGIN_ERROR_RETRY_DELAY
if lrle_resp is LoginRateLimitErrResp.RETRY:
delay = LOGIN_ERROR_RETRY_DELAY
else:
delay = 0
delay_reason = "login error"
login_error_retries += 1
continue

treat_as_error = lrle_resp is not LoginRateLimitErrorResp.SILENT
treat_as_error = lrle_resp is not LoginRateLimitErrResp.SILENT
self._set_acct_exc(aid, not treat_as_error, msg, exc)
if treat_as_error:
self._handle_login_error(aid)
return RequestError.NO_DATA

except Life360Error as exc:
rate_limited = isinstance(exc, RateLimited)
if lrle_resp is LoginRateLimitErrorResp.RETRY and rate_limited:
if lrle_resp is LoginRateLimitErrResp.RETRY and rate_limited:
self._set_acct_exc(aid)
delay = ceil(cast(RateLimited, exc).retry_after or 0) + 10
delay_reason = "rate limited"
continue

treat_as_error = not (
rate_limited and lrle_resp is LoginRateLimitErrorResp.SILENT
rate_limited and lrle_resp is LoginRateLimitErrResp.SILENT
)
self._set_acct_exc(aid, not treat_as_error, msg, exc)
return RequestError.NO_DATA

except asyncio.CancelledError:
if request_task:
request_task.cancel()
Expand Down

0 comments on commit ed42c71

Please sign in to comment.