Skip to content

Commit 31020b6

Browse files
committed
store: Handle invalid API key on register-queue
This fixes the user reported issue by navigating them back to the choose-account page if the API key is found invalid: https://chat.zulip.org/#narrow/channel/48-mobile/topic/0.2E0.2E19.20Flutter.20.3A.20Cant.20connect.20to.20self.20hosted.20instance/near/2004042 A follow-up would be bringing the user back to the login page (so that the realm url is pre-filled). Signed-off-by: Zixuan James Li <[email protected]>
1 parent 08e4f6a commit 31020b6

14 files changed

+159
-7
lines changed

assets/l10n/app_en.arb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,13 @@
458458
"@topicValidationErrorMandatoryButEmpty": {
459459
"description": "Topic validation error when topic is required but was empty."
460460
},
461+
"errorInvalidApiKeyMessage": "Your account at {url} cannot be authenticated. Please try again or use another account.",
462+
"@errorInvalidApiKeyMessage": {
463+
"description": "Error message in the dialog for invalid API key.",
464+
"placeholders": {
465+
"url": {"type": "String", "example": "http://chat.example.com/"}
466+
}
467+
},
461468
"errorInvalidResponse": "The server sent an invalid response",
462469
"@errorInvalidResponse": {
463470
"description": "Error message when an API call returned an invalid response."

lib/generated/l10n/zulip_localizations.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,12 @@ abstract class ZulipLocalizations {
721721
/// **'Topics are required in this organization.'**
722722
String get topicValidationErrorMandatoryButEmpty;
723723

724+
/// Error message in the dialog for invalid API key.
725+
///
726+
/// In en, this message translates to:
727+
/// **'Your account at {url} cannot be authenticated. Please try again or use another account.'**
728+
String errorInvalidApiKeyMessage(String url);
729+
724730
/// Error message when an API call returned an invalid response.
725731
///
726732
/// In en, this message translates to:

lib/generated/l10n/zulip_localizations_ar.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
357357
@override
358358
String get topicValidationErrorMandatoryButEmpty => 'Topics are required in this organization.';
359359

360+
@override
361+
String errorInvalidApiKeyMessage(String url) {
362+
return 'Your account at $url cannot be authenticated. Please try again or use another account.';
363+
}
364+
360365
@override
361366
String get errorInvalidResponse => 'The server sent an invalid response';
362367

lib/generated/l10n/zulip_localizations_en.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
357357
@override
358358
String get topicValidationErrorMandatoryButEmpty => 'Topics are required in this organization.';
359359

360+
@override
361+
String errorInvalidApiKeyMessage(String url) {
362+
return 'Your account at $url cannot be authenticated. Please try again or use another account.';
363+
}
364+
360365
@override
361366
String get errorInvalidResponse => 'The server sent an invalid response';
362367

lib/generated/l10n/zulip_localizations_fr.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ class ZulipLocalizationsFr extends ZulipLocalizations {
357357
@override
358358
String get topicValidationErrorMandatoryButEmpty => 'Topics are required in this organization.';
359359

360+
@override
361+
String errorInvalidApiKeyMessage(String url) {
362+
return 'Your account at $url cannot be authenticated. Please try again or use another account.';
363+
}
364+
360365
@override
361366
String get errorInvalidResponse => 'The server sent an invalid response';
362367

lib/generated/l10n/zulip_localizations_ja.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
357357
@override
358358
String get topicValidationErrorMandatoryButEmpty => 'Topics are required in this organization.';
359359

360+
@override
361+
String errorInvalidApiKeyMessage(String url) {
362+
return 'Your account at $url cannot be authenticated. Please try again or use another account.';
363+
}
364+
360365
@override
361366
String get errorInvalidResponse => 'The server sent an invalid response';
362367

lib/generated/l10n/zulip_localizations_pl.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
357357
@override
358358
String get topicValidationErrorMandatoryButEmpty => 'Wątki są wymagane przez tę organizację.';
359359

360+
@override
361+
String errorInvalidApiKeyMessage(String url) {
362+
return 'Your account at $url cannot be authenticated. Please try again or use another account.';
363+
}
364+
360365
@override
361366
String get errorInvalidResponse => 'Nieprawidłowa odpowiedź serwera';
362367

lib/generated/l10n/zulip_localizations_ru.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
357357
@override
358358
String get topicValidationErrorMandatoryButEmpty => 'Topics are required in this organization.';
359359

360+
@override
361+
String errorInvalidApiKeyMessage(String url) {
362+
return 'Your account at $url cannot be authenticated. Please try again or use another account.';
363+
}
364+
360365
@override
361366
String get errorInvalidResponse => 'The server sent an invalid response';
362367

lib/model/store.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,12 @@ class UpdateMachine {
912912
// at 1 kiB (at least on Android), and stack can be longer than that.
913913
assert(debugLog('Stack:\n$s'));
914914
assert(debugLog('Backing off, then will retry…'));
915-
// TODO tell user if initial-fetch errors persist, or look non-transient
915+
// TODO(#890): tell user if initial-fetch errors persist, or look non-transient
916+
switch (e) {
917+
case ZulipApiException(code: 'INVALID_API_KEY'):
918+
// See also: [_PerAccountStoreWidgetState.didChangeDependencies]
919+
rethrow;
920+
}
916921
await (backoffMachine ??= BackoffMachine()).wait();
917922
assert(debugLog('… Backoff wait complete, retrying initial fetch.'));
918923
}

lib/widgets/app.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@ class _ZulipAppState extends State<ZulipApp> with WidgetsBindingObserver {
233233
class ChooseAccountPage extends StatelessWidget {
234234
const ChooseAccountPage({super.key});
235235

236+
/// Navigate to [ChooseAccountPage], ensuring that its route is at the root level.
237+
static void navigate(BuildContext context) {
238+
final navigator = Navigator.of(context);
239+
navigator.popUntil((route) => route.isFirst);
240+
unawaited(navigator.pushReplacement(
241+
MaterialWidgetRoute(page: const ChooseAccountPage())));
242+
}
243+
236244
Widget _buildAccountItem(
237245
BuildContext context, {
238246
required int accountId,

0 commit comments

Comments
 (0)