Skip to content

Commit 33c365a

Browse files
PIG208gnprice
authored andcommitted
store: Ignore boring NetworkExceptions
Usually when a client goes back from sleep or lose network connection, there will be a bunch of errors when polling event queue. This known error will always be a `NetworkException`, so we make a separate case for it. Previously, we may report these errors, and it ended up being spammy. This filters out the more interesting one to report instead. Fixes: #555 Signed-off-by: Zixuan James Li <[email protected]>
1 parent 4fdeb27 commit 33c365a

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

lib/model/store.dart

+16-1
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ class UpdateMachine {
964964
debugLog('… Event queue replaced.');
965965
return;
966966

967-
case Server5xxException() || NetworkException():
967+
case Server5xxException():
968968
assert(debugLog('Transient error polling event queue for $store: $e\n'
969969
'Backing off, then will retry…'));
970970
maybeReportTransientError(
@@ -975,6 +975,21 @@ class UpdateMachine {
975975
assert(debugLog('… Backoff wait complete, retrying poll.'));
976976
continue;
977977

978+
case NetworkException():
979+
assert(debugLog('Transient error polling event queue for $store: $e\n'
980+
'Backing off, then will retry…'));
981+
if (e.cause is! SocketException) {
982+
// Heuristic check to only report interesting errors to the user.
983+
// A [SocketException] is common when the app returns from sleep.
984+
maybeReportTransientError(
985+
localizations.errorConnectingToServerShort,
986+
details: localizations.errorConnectingToServerDetails(
987+
serverUrl, e.toString()));
988+
}
989+
await (backoffMachine ??= BackoffMachine()).wait();
990+
assert(debugLog('… Backoff wait complete, retrying poll.'));
991+
continue;
992+
978993
default:
979994
assert(debugLog('Error polling event queue for $store: $e\n'
980995
'Backing off and retrying even though may be hopeless…'));

test/model/store_test.dart

+19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:async';
2+
import 'dart:io';
23

34
import 'package:checks/checks.dart';
45
import 'package:fake_async/fake_async.dart';
@@ -717,6 +718,24 @@ void main() {
717718
"Error connecting to Zulip. Retrying…\n"
718719
"Error connecting to Zulip at");
719720
}));
721+
722+
test('ignore boring errors', () => awaitFakeAsync((async) async {
723+
await prepare();
724+
725+
for (int i = 0; i < UpdateMachine.transientFailureCountNotifyThreshold; i++) {
726+
connection.prepare(exception: const SocketException('failed'));
727+
pollAndFail(async);
728+
check(takeLastReportedError()).isNull();
729+
// This skips the pending polling backoff.
730+
async.flushTimers();
731+
}
732+
733+
connection.prepare(exception: const SocketException('failed'));
734+
pollAndFail(async);
735+
// Normally we start showing user visible error messages for transient
736+
// errors after enough number of retries.
737+
check(takeLastReportedError()).isNull();
738+
}));
720739
});
721740
});
722741

0 commit comments

Comments
 (0)