Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion lib/screens/sell/cubits/sell_balance/sell_balance_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:developer' as developer;

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:realunit_wallet/models/balance.dart';
Expand All @@ -19,7 +20,21 @@ class SellBalanceCubit extends Cubit<Balance> {
asset: appStore.apiConfig.asset,
),
) {
_subscription = _repository.watchBalance(state).listen(emit);
// Register an onError handler so a balance-stream error is logged instead
// of escaping as an unhandled async error that silently stops the sell
// balance (issue #657 P4 S6). cancelOnError defaults to false, so the
// subscription stays alive and later balances still update.
_subscription = _repository.watchBalance(state).listen(
emit,
onError: (Object error, StackTrace stackTrace) {
developer.log(
'sell balance stream error',
name: '$SellBalanceCubit',
error: error,
stackTrace: stackTrace,
);
},
);
}

final BalanceRepository _repository;
Expand Down
25 changes: 25 additions & 0 deletions test/screens/sell/cubits/sell_balance_cubit_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,31 @@ void main() {
expect(cubit.state.balance, BigInt.from(7000));
});

test(
'a stream error is handled (not unhandled) and later balances still '
'update (issue #657 P4 S6 regression)', () async {
final cubit = SellBalanceCubit(repo, appStore);

// Without an onError handler this error escaped as an unhandled async
// error (failing the test) and stopped the sell balance. It must now be
// logged, and — cancelOnError being false — a later balance still lands.
controller.addError(Exception('balance backend blip'));
await Future<void>.delayed(Duration.zero);

final updated = Balance(
chainId: realUnitAsset.chainId,
contractAddress: realUnitAsset.address,
walletAddress: _wallet,
balance: BigInt.from(4242),
asset: realUnitAsset,
);
final ready = cubit.stream.firstWhere((b) => b.balance == BigInt.from(4242));
controller.add(updated);
await ready.timeout(const Duration(seconds: 1));

expect(cubit.state.balance, BigInt.from(4242));
});

test('close() cancels the subscription cleanly', () async {
final cubit = SellBalanceCubit(repo, appStore);

Expand Down
Loading