Ошибка в потоке в Dart
Исключение в генераторе или в операторе рвет
чтение, если его не обработать. Метод
handleError вешают на Stream:
при ошибке вызывается переданная функция, и
поток может завершиться штатно.
Сбой внутри async* ловят до того, как
await for увидит необработанное
исключение:
import 'dart:async';
Stream<int> risky() async* {
yield 1;
throw StateError('broken');
}
void main() async {
Stream<int> safe = risky().handleError((Object e) {
print('handled');
});
await for (int n in safe) {
print(n);
}
}
Сначала печатается 1, затем метка
"handled". handleError срабатывает
на ошибке после первого элемента и не дает
чтению упасть наружу.
Тот же прием работает перед listen.
Во втором аргументе listen можно
передать onError, если обработчик нужен
рядом с подпиской:
import 'dart:async';
Stream<String> risky() async* {
yield 'ok';
throw StateError('fail');
}
void main() {
risky().listen(
(String line) {
print(line);
},
onError: (Object e) {
print('fallback');
},
);
}
В консоли "ok" и "fallback".
Вторая строка приходит уже из onError,
а не из исходного генератора.
Поток отдает 5, затем бросает
исключение с текстом "stop".
Подключите handleError, который печатает
"recovered", и прочитайте поток в
await for.
После строки "live" выбросьте ошибку.
В onError у listen напечатайте
"spare" и убедитесь, что программа
заканчивается без необработанного исключения.