@@ -22,6 +22,7 @@ import '../notifications/receive.dart';
22
22
import 'autocomplete.dart' ;
23
23
import 'database.dart' ;
24
24
import 'emoji.dart' ;
25
+ import 'localizations.dart' ;
25
26
import 'message.dart' ;
26
27
import 'message_list.dart' ;
27
28
import 'recent_dm_conversations.dart' ;
@@ -912,10 +913,28 @@ class UpdateMachine {
912
913
}());
913
914
}
914
915
916
+ /// This controls when we start to report transient errors to the user when
917
+ /// polling.
918
+ ///
919
+ /// At the 6th failure, the expected time elapsed since the first failure
920
+ /// will be 1.55 seocnds.
921
+ static const transientFailureCountNotifyThreshold = 5 ;
922
+
915
923
void poll () async {
916
924
assert (! _disposed);
917
925
918
926
BackoffMachine ? backoffMachine;
927
+ int accumulatedTransientFailureCount = 0 ;
928
+
929
+ /// This only reports transient errors after reaching
930
+ /// a pre-defined threshold of retries.
931
+ void maybeReportTransientError (String ? message, {String ? details}) {
932
+ accumulatedTransientFailureCount++ ;
933
+ if (accumulatedTransientFailureCount > transientFailureCountNotifyThreshold) {
934
+ reportErrorToUserBriefly (message, details: details);
935
+ }
936
+ }
937
+
919
938
while (true ) {
920
939
if (_debugLoopSignal != null ) {
921
940
await _debugLoopSignal! .future;
@@ -935,6 +954,8 @@ class UpdateMachine {
935
954
if (_disposed) return ;
936
955
937
956
store.isLoading = true ;
957
+ final localizations = GlobalLocalizations .zulipLocalizations;
958
+ final serverUrl = store.connection.realmUrl.origin;
938
959
switch (e) {
939
960
case ZulipApiException (code: 'BAD_EVENT_QUEUE_ID' ):
940
961
assert (debugLog ('Lost event queue for $store . Replacing…' ));
@@ -946,15 +967,22 @@ class UpdateMachine {
946
967
case Server5xxException () || NetworkException ():
947
968
assert (debugLog ('Transient error polling event queue for $store : $e \n '
948
969
'Backing off, then will retry…' ));
949
- // TODO tell user if transient polling errors persist
970
+ maybeReportTransientError (
971
+ localizations.errorConnectingToServerShort,
972
+ details: localizations.errorConnectingToServerDetails (
973
+ serverUrl, e.toString ()));
950
974
await (backoffMachine ?? = BackoffMachine ()).wait ();
951
975
assert (debugLog ('… Backoff wait complete, retrying poll.' ));
952
976
continue ;
953
977
954
978
default :
955
979
assert (debugLog ('Error polling event queue for $store : $e \n '
956
980
'Backing off and retrying even though may be hopeless…' ));
957
- // TODO tell user on non-transient error in polling
981
+ // TODO(#186): Handle unrecoverable failures
982
+ reportErrorToUserBriefly (
983
+ localizations.errorConnectingToServerShort,
984
+ details: localizations.errorConnectingToServerDetails (
985
+ serverUrl, e.toString ()));
958
986
await (backoffMachine ?? = BackoffMachine ()).wait ();
959
987
assert (debugLog ('… Backoff wait complete, retrying poll.' ));
960
988
continue ;
@@ -978,6 +1006,9 @@ class UpdateMachine {
978
1006
// and failures, the successes themselves should space out the requests.
979
1007
backoffMachine = null ;
980
1008
store.isLoading = false ;
1009
+ // Dismiss existing errors, if any.
1010
+ reportErrorToUserBriefly (null );
1011
+ accumulatedTransientFailureCount = 0 ;
981
1012
982
1013
final events = result.events;
983
1014
for (final event in events) {
0 commit comments