Skip to content

Complete OtfCognito's public error boundary at login_with_password and renew_access_token #143

Description

@jessica-claude

Description

OtfCognito still leaks raw botocore exceptions from two public call sites in src/otf_api/auth/auth.py, despite the error boundary established in #141 (_create_cognito in user.py) and its follow-up commit (check_token in auth.py, same PR #142). login_with_password only handles ClientError for its retry-on-UserLambdaValidationException path and bare-raises everything else, with no BotoCoreError handling at all. renew_access_token has no exception handling whatsoever — both ClientError and BotoCoreError propagate straight to callers with raw provider text.

These were identified during code review of PR #142 as pre-existing gaps with the same shape #141 targeted, but out of scope for that PR.

Acceptance Criteria

  • login_with_password catches ClientError for the non-retryable case and raises OtfAuthenticationError with a fixed safe message (from e), preserving the existing retry-on-UserLambdaValidationException behavior
  • login_with_password catches BotoCoreError and raises OtfTransportError with a fixed safe message (from e)
  • renew_access_token wraps self.idp_client.initiate_auth(...), catching ClientError -> OtfAuthenticationError and BotoCoreError -> OtfTransportError, both with fixed safe messages and from e
  • Raw botocore/Cognito exception text no longer reaches callers of either method
  • Tests pass — existing tests updated, new tests added covering the new exception-mapping behavior for both methods

Affected Areas

  • src/otf_api/auth/auth.py — login_with_password (roughly lines 232-265): add BotoCoreError handling and replace the bare raise for non-retryable ClientError with OtfAuthenticationError from e, keeping the existing retry logic intact
  • src/otf_api/auth/auth.py — renew_access_token (roughly lines 343-363): wrap the self.idp_client.initiate_auth(...) call with ClientError/BotoCoreError handling; this method currently has none of the except-branch scaffolding the other two fixed call sites had, so it needs to be built from scratch
  • tests/test_auth/test_otf_cognito.py — add coverage for the new exception mapping on both methods

Context

Follow the pattern established in _create_cognito (src/otf_api/auth/user.py:23-38) and check_token (src/otf_api/auth/auth.py:313-341):

except ClientError as e:
    ...
    raise OtfAuthenticationError("OTF authentication failed") from e
except BotoCoreError as e:
    # ClientError is a sibling of BotoCoreError, not a subclass, so this branch only ever
    # sees non-API failures (connectivity, timeout, endpoint resolution).
    LOGGER.exception("Transport error while ...")
    raise OtfTransportError("OTF transport error") from e

Constraints:

  • login_with_password's existing retry-on-UserLambdaValidationException logic (checking e.response["Error"]["Code"] / ["Message"] and retrying once after a 5s sleep) must be preserved — only the non-retryable fallthrough path changes from a bare raise to raise OtfAuthenticationError(...) from e.
  • renew_access_token has no existing except branches at all — this is new exception handling, not a preserve-and-extend edit like the other two call sites.
  • OtfAuthenticationError and OtfTransportError are defined in src/otf_api/exceptions.py; both expose the original exception via __cause__.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions