Skip to content

login(): surface the API status code and raise a dedicated error for status 202 (login needs e-mail confirmation) #8

Description

@dvejsada

What happens

Rohlík's login endpoint can answer with status: 202 instead of 200, with no message and no session:

{"status": 202, "messages": [], "data": null}

AuthManager.login() collapses every non-200, non-401 body status into the base RohlikAPIError, and because messages is empty the message degenerates to a tautology:

RohlikAPIError("Unknown error occurred during login: Unknown error")

The status code (202) and the response body are dropped, and nothing is logged. A consumer cannot tell this apart from a genuine server error, and the field report carries no usable information.

What 202 appears to mean

Rohlík's own login page (/uzivatel/prihlaseni) ships these strings:

"Pro dokončení přihlášení klikněte na odkaz, který jsme vám poslali na adresu {{email}}"
"Zbývá jen potvrdit e-mail"

Their route table also has magicLink → /magic-login/keep-account, verificationEmail → /verification/email, plus Google/Apple/Facebook login callbacks.

That is exactly HTTP 202 Accepted semantics for a login: the request was accepted, but the login is not complete until the user clicks a link Rohlík e-mails them, so no session is issued. messages is empty because it is not an error — the web app switches to a "confirm your e-mail" screen off the status code alone. The keep-account magic-link route suggests this also covers accounts tied to a social login.

Worth stating plainly: this is inferred from their frontend, not from documentation, and I have not observed a 202 myself (it needs an account in that state). What is verified is that the client's request shape is not the cause — a cookie-less POST with the default rohlik-api-python/<ver> User-Agent and a non-existent e-mail returns a clean 401 with messageCode: login.invalid_credentials, so there is no anti-bot gate on this endpoint.

Why it matters

A consumer (e.g. the Home Assistant integration) currently has to report "unknown error" or "cannot connect" for what is really "go click the link in your inbox, then retry". It also cannot decide whether to retry the request (pointless here) or to ask the user to act.

Proposal

  1. Add a dedicated exception for the incomplete-login case, e.g. LoginNotCompletedError(RohlikAPIError), raised when the login body status is 202.
  2. Carry the API status on the error so consumers can branch on codes this library does not yet know about — e.g. an optional status: int | None attribute on RohlikAPIError (or at minimum include the numeric status in the message).
  3. Log the failing login body at debug through the existing mask_data helper, and include the status in the exception message, so a field report is diagnosable:
    RohlikAPIError("Login failed with status 202: <detail>").

While in there: login()'s docstring advertises APIRequestFailedError for a failed login request, but the body-status path raises the bare RohlikAPIError — worth aligning the docstring with the behaviour (and making the raised types explicit) as part of this change.

Downstream consumer issue: dvejsada/HA-RohlikCZ#86. Original user report: dvejsada/HA-RohlikCZ#79.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions