@@ -1175,7 +1175,7 @@ class UpdateMachine {
11751175 InitialSnapshot ? result;
11761176 try {
11771177 result = await registerQueue (connection);
1178- } catch (e, s ) {
1178+ } catch (e, stackTrace ) {
11791179 stopAndThrowIfNoAccount ();
11801180 // TODO(#890): tell user if initial-fetch errors persist, or look non-transient
11811181 final ZulipVersionData ? zulipVersionData;
@@ -1192,7 +1192,20 @@ class UpdateMachine {
11921192 assert (debugLog ('Error fetching initial snapshot: $e ' ));
11931193 // Print stack trace in its own log entry; log entries are truncated
11941194 // at 1 kiB (at least on Android), and stack can be longer than that.
1195- assert (debugLog ('Stack:\n $s ' ));
1195+ assert (debugLog ('Stack:\n $stackTrace ' ));
1196+ if (e case NetworkException (cause: SocketException ())) {
1197+ // A [SocketException] is common when the device is asleep.
1198+ } else {
1199+ // TODO: When the error seems transient, do keep retrying but
1200+ // don't spam this feedback.
1201+ // TODO(#1948) Break the retry loop on non-transient errors.
1202+ _reportConnectionErrorToUserAndPromiseRetry (e,
1203+ realmUrl: connection.realmUrl,
1204+ // The stack trace is mostly useful for
1205+ // `MalformedServerResponseException`s, and will be noise for
1206+ // routine exceptions like from network problems.
1207+ stackTrace: e is ApiRequestException ? null : stackTrace);
1208+ }
11961209 }
11971210 assert (debugLog ('Backing off, then will retry…' ));
11981211 await (backoffMachine ?? = BackoffMachine ()).wait ();
@@ -1498,7 +1511,9 @@ class UpdateMachine {
14981511 // at 1 kiB (at least on Android), and stack can be longer than that.
14991512 assert (debugLog ('Stack trace:\n $stackTrace ' ));
15001513 assert (debugLog ('Replacing event queue…' ));
1501- _reportToUserErrorConnectingToServer (error, stackTrace);
1514+ _reportConnectionErrorToUserAndPromiseRetry (error,
1515+ realmUrl: store.realmUrl,
1516+ stackTrace: stackTrace);
15021517 // Similar story to the _EventHandlingException case;
15031518 // separate only so that that other case can print more context.
15041519 // The bug here could be in the server if it's an ApiRequestException,
@@ -1529,11 +1544,17 @@ class UpdateMachine {
15291544 void _maybeReportToUserTransientError (Object error) {
15301545 _accumulatedTransientFailureCount++ ;
15311546 if (_accumulatedTransientFailureCount > transientFailureCountNotifyThreshold) {
1532- _reportToUserErrorConnectingToServer (error);
1547+ _reportConnectionErrorToUserAndPromiseRetry (error, realmUrl : store.realmUrl );
15331548 }
15341549 }
15351550
1536- void _reportToUserErrorConnectingToServer (Object error, [StackTrace ? stackTrace]) {
1551+ /// Give brief UI feedback that we failed to connect to the server
1552+ /// and that we'll try again.
1553+ static void _reportConnectionErrorToUserAndPromiseRetry (
1554+ Object error, {
1555+ StackTrace ? stackTrace,
1556+ required Uri realmUrl,
1557+ }) {
15371558 final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
15381559
15391560 final details = StringBuffer ()..write (error.toString ());
@@ -1544,7 +1565,7 @@ class UpdateMachine {
15441565 reportErrorToUserBriefly (
15451566 zulipLocalizations.errorConnectingToServerShort,
15461567 details: zulipLocalizations.errorConnectingToServerDetails (
1547- store. realmUrl.toString (), details.toString ()));
1568+ realmUrl.toString (), details.toString ()));
15481569 }
15491570
15501571 /// Cleans up resources and tells the instance not to make new API requests.
0 commit comments