@@ -16,6 +16,7 @@ import '../api/model/model_checks.dart';
16
16
import '../example_data.dart' as eg;
17
17
import '../fake_async.dart' ;
18
18
import '../stdlib_checks.dart' ;
19
+ import '../test_log.dart' ;
19
20
import 'binding.dart' ;
20
21
import 'store_checks.dart' ;
21
22
import 'test_store.dart' ;
@@ -405,7 +406,8 @@ void main() {
405
406
});
406
407
updateMachine.debugAdvanceLoop ();
407
408
async .flushMicrotasks ();
408
- await Future <void >.delayed (Duration .zero);
409
+ (await checkLogs (() async => await Future <void >.delayed (Duration .zero)))
410
+ .any ((s) => s.contains ('Reconnecting to server.' ));
409
411
check (store).isLoading.isTrue ();
410
412
411
413
// The global store has a new store.
@@ -427,20 +429,36 @@ void main() {
427
429
check (store.userSettings! .twentyFourHourTime).isTrue ();
428
430
}));
429
431
430
- void checkRetry (String description, void Function () prepareError) {
432
+ void checkRetry (String description, void Function () prepareError, {
433
+ String ? errorMessage,
434
+ int numRetries = 1 ,
435
+ }) {
431
436
test (description, () {
432
437
awaitFakeAsync ((async ) async {
433
438
await prepareStore (lastEventId: 1 );
434
439
updateMachine.debugPauseLoop ();
435
440
updateMachine.poll ();
436
441
check (async .pendingTimers).length.equals (0 );
437
442
438
- // Make the request, inducing an error in it.
439
- prepareError ();
440
- updateMachine.debugAdvanceLoop ();
441
- async .elapse (Duration .zero);
442
- checkLastRequest (lastEventId: 1 );
443
- check (store).isLoading.isTrue ();
443
+ for (int i = 0 ; i < numRetries; i++ ) {
444
+ // Make the request, inducing an error in it.
445
+ prepareError ();
446
+ async .flushTimers ();
447
+ updateMachine.debugAdvanceLoop ();
448
+ if (errorMessage != null ) {
449
+ if (i < numRetries - 1 ) {
450
+ (await checkLogs (() => async .elapse (Duration .zero)))
451
+ .every ((s) => s.not ((s) => s.contains (errorMessage)));
452
+ } else {
453
+ (await checkLogs (() => async .elapse (Duration .zero)))
454
+ .any ((s) => s.contains (errorMessage));
455
+ }
456
+ } else {
457
+ async .elapse (Duration .zero);
458
+ }
459
+ checkLastRequest (lastEventId: 1 );
460
+ check (store).isLoading.isTrue ();
461
+ }
444
462
445
463
// Polling doesn't resume immediately; there's a timer.
446
464
check (async .pendingTimers).length.equals (1 );
@@ -468,12 +486,24 @@ void main() {
468
486
checkRetry ('retries on NetworkException' ,
469
487
() => connection.prepare (exception: Exception ("failed" )));
470
488
489
+ checkRetry ('too many retries on Server5xxException' ,
490
+ () => connection.prepare (exception: Exception ("failed" )),
491
+ errorMessage: 'Failed to reach server. Will retry' ,
492
+ numRetries: 11 );
493
+
494
+ checkRetry ('too many retries on NetworkException' ,
495
+ () => connection.prepare (exception: Exception ("failed" )),
496
+ errorMessage: 'Failed to reach server. Will retry' ,
497
+ numRetries: 11 );
498
+
471
499
checkRetry ('retries on ZulipApiException' ,
472
500
() => connection.prepare (httpStatus: 400 , json: {
473
- 'result' : 'error' , 'code' : 'BAD_REQUEST' , 'msg' : 'Bad request' }));
501
+ 'result' : 'error' , 'code' : 'BAD_REQUEST' , 'msg' : 'Bad request' }),
502
+ errorMessage: 'Error loading server data. Will retry' );
474
503
475
504
checkRetry ('retries on MalformedServerResponseException' ,
476
- () => connection.prepare (httpStatus: 200 , body: 'nonsense' ));
505
+ () => connection.prepare (httpStatus: 200 , body: 'nonsense' ),
506
+ errorMessage: 'Error loading server data. Will retry' );
477
507
});
478
508
});
479
509
0 commit comments