Repository navigation
COR-255 - Report a login refused as temporarily unavailable as its own error - #122
Merged
Merged
Conversation
…OR-255 A server can refuse a login with the RFC 5530 code `UNAVAILABLE`: Yahoo answers `NO [UNAVAILABLE] AUTHENTICATE Server error - Please try again later` about nine seconds after the command, iCloud `BAD [UNAVAILABLE] Service temporarily unavailable`, Dovecot servers in their own words. No text matched, so the login reported `ErrorAuthentication`, and the client treated a temporary failure as a wrong password: auth-failed mark, password prompt, forced token refresh, pool rebuild and a retry every few seconds against a server that was refusing for another reason. `IMAPSession::login` now reads the code of the parsed reply (`imap_response_info->rsp_atom`, rebuilt by libetpan on every parsed reply) after `MAILIMAP_ERROR_LOGIN` or `MAILIMAP_ERROR_PROTOCOL` (BAD) and reports the new `ErrorIMAPUnavailable`, with `mShouldDisconnect` so the next login starts on a fresh connection. The check comes after the connection-limit texts: a refusal that names the limit stays the limit. The code is appended after `ErrorIMAPTooManySimultaneousConnections` in the C++, C and Swift enums; like it, it has no ObjC constant and no localized description. Tests: `IMAPLoginTests` against `LeaseTestTCPEndpoint`, for LOGIN, XOAUTH2, SASL PLAIN and SASL LOGIN. `NO [UNAVAILABLE]` gave 5 and `BAD [UNAVAILABLE]` gave 1 before the fix; `[UNAVAILABLE]` with the limit text, wrong credentials and a bare BYE keep their codes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Collaborator
Author
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit db12d3c. Configure here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A server can refuse a login with the RFC 5530 response code
UNAVAILABLE— a temporary failure on its side, not the credentials. Yahoo answersNNN NO [UNAVAILABLE] AUTHENTICATE Server error - Please try again laterabout nine seconds after the command (30% of Yahoo mailboxes a day in production, 89% of the episodes clear on the next attempt), iCloud answersBAD [UNAVAILABLE] Service temporarily unavailable, Dovecot servers (iiNet, the report in COR-255)NO [UNAVAILABLE] Account is temporarily unavailable.. No login text matched, so mailcore reportedErrorAuthenticationand Spark treated the refusal as a wrong password: auth-failed mark, password prompt, forced OAuth refresh, rebuild of every pool and a retry every ~9 s — against a server that, per production data, keeps refusing longer when a client keeps knocking.IMAPSession::loginreads the RFC 5530 code of the reply libetpan parsed (imap_response_info->rsp_atom, rebuilt on every parsed reply) afterMAILIMAP_ERROR_LOGINorMAILIMAP_ERROR_PROTOCOL(the BAD form) and reports the newErrorIMAPUnavailable, withmShouldDisconnectso that the next login starts on a fresh connection. The parsed field, not the text: libetpan strips the bracketed code out ofimap_response, so a text match would never see it, and the[LIMIT]check reads the raw stream buffer only because libetpan stops at* BYEbefore parsing the tagged line.NO [UNAVAILABLE] Maximum number of connections …staysErrorGmailTooManySimultaneousConnections, the more specific answer with the pool narrowing it calls for.ErrorIMAPTooManySimultaneousConnections(50) in the C++, C and Swift enums; like it, no ObjC constant and no localized description. iCloud'sBAD [UNAVAILABLE]moves fromErrorConnectionto the new code; Spark maps both to its connection error.Spark's side (mapping, the pause before the next attempt, discovery, health counter) is the core PR for COR-255; it needs this change released and the pin bumped.
The C++ changed, so the Windows prebuilt needs a rebuild for this revision before a tag.
Tests:
IMAPLoginTestsagainstLeaseTestTCPEndpoint, each refusal for LOGIN, XOAUTH2, SASL PLAIN and SASL LOGIN.NO [UNAVAILABLE]gave 5 andBAD [UNAVAILABLE]gave 1 before the fix;[UNAVAILABLE]with the limit text, wrong credentials, Gmail's text and a bare BYE keep their codes. The wire shape matches the user logs attached to COR-255 and the Mac/iOS support logs: one tagged line, no* BYE, no continuation.🤖 Generated with Claude Code
Note
Medium Risk
Changes IMAP login error classification and appends a new enum value; downstream clients must handle the new code, but scope is limited to login failure mapping.
Overview
Adds
ErrorIMAPUnavailableacross the C/C++/Swift error enums so IMAP login failures with RFC 5530[UNAVAILABLE]are not reported asErrorAuthentication.IMAPSession::loginnow reads the parsed response code from libetpan (imap_response_info->rsp_atom) when login returnsMAILIMAP_ERROR_LOGINorMAILIMAP_ERROR_PROTOCOL(e.g. iCloud’sBAD [UNAVAILABLE]). It mapsUNAVAILABLEto the new error and setsmShouldDisconnectso the next attempt uses a fresh connection. Connection-limit message checks still run first, soNO [UNAVAILABLE]with “Maximum number of connections” text staysErrorGmailTooManySimultaneousConnections.IMAPLoginTestscover LOGIN, XOAUTH2, SASL PLAIN, and SASL LOGIN, includingNO/BAD [UNAVAILABLE], precedence over limit text, and unchanged behavior for wrong credentials and other refusals.Reviewed by Cursor Bugbot for commit db12d3c. Bugbot is set up for automated code reviews on this repo. Configure here.