Как управлять исключениями блоков, созданными с помощью StreamBuilder? - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь вернуть состояние ошибки моментального снимка в StreamBuilder, когда у моего провайдера возникли проблемы во время вызова http.get(). В моем случае я выбрасываю исключение, когда http.get() возвращает состояние, отличное от 200 (ОК). Я хотел бы иметь возможность вернуть плохое состояние снимка и выполнить определенный код для этой ситуации. Теперь, когда я выкидываю исключение, приложение просто падает.

Поставщик:

class FmsApiProvider {
  Future<List<FmsListResponse>> fetchFmsList() async {
    print("Starting fetch FMS..");
    final Response response = await httpGet('fms');
    if (response.statusCode == HttpStatus.ok) {
      // If the call to the server was successful, parse the JSON
      return fmsListResponseFromJson(response.body);
    } else {
      // If that call was not successful, throw an error.
      //return Future.error(List<FmsListResponse>());
      throw Exception('Failed to load FMSs');
    }
  }
}

Repository:

class Repository {
  final fmsApiProvider = FmsApiProvider();

  Future<List<FmsListResponse>> fetchAllFms() => fmsApiProvider.fetchFmsList();
}

Блок:

class FmsBloc {
  final _fmsRepository = Repository();

  final _fmsFetcher = PublishSubject<List<FmsListResponse>>();

  Observable<List<FmsListResponse>> get allFms => _fmsFetcher.stream;

  fetchAllFms() async {
    List<FmsListResponse> itemModel = await _fmsRepository.fetchAllFms();
    _fmsFetcher.sink.add(itemModel);
  }

  dispose() {
    _fmsFetcher.close();
  }
}

Мой StreamBuilder:

StreamBuilder(
            stream: bloc.allFms,
            builder: (context, AsyncSnapshot<List<FmsListResponse>> snapshot) {
              if (snapshot.hasData) {
                return RefreshIndicator(
                    onRefresh: () async {
                      bloc.fetchAllFms();
                    },
                    color: globals.fcsBlue,
                    child: ScrollConfiguration(
                      behavior: NoOverScrollBehavior(),
                      child: ListView.builder(
                          shrinkWrap: true,
                          itemCount:
                              snapshot.data != null ? snapshot.data.length : 0,
                          itemBuilder: (BuildContext context, int index) {
                            final fms = snapshot.data[index];
                            //Fill a global list that contains the FMS for this instances
                            globals.currentFMSs.add(
                                FMSBasicInfo(id: fms.id, code: fms.fmsCode));
                            return MyCard(
                              title: _titleContainer(fms.fmsData),
                              fmsId: fms.id,
                              wmId: fms.fmsData.workMachinesList.first
                                  .id, //pass the firs element only for compose the image url
                              imageType: globals.ImageTypeEnum.iteCellLayout,
                              scaleFactor: 4,
                              onPressed: () => _onPressed(fms),
                            );
                          }),
                    ));
              } else if (snapshot.hasError) {
                return Text('Fms snapshot error!');
              }
              return FCSLoader();
            })

Когда выдается исключение, я хотел бы получить ошибку моментального снимка, а затем визуализировать только текст на моей странице.

1 Ответ

0 голосов
/ 20 июня 2019

Вы должны обернуть вызов API в триггер try, а затем добавить ошибку в свой приемник.

class FmsBloc {
  final _fmsRepository = Repository();

  final _fmsFetcher = PublishSubject<List<FmsListResponse>>();

  Observable<List<FmsListResponse>> get allFms => _fmsFetcher.stream;

  fetchAllFms() async {
    try {
      List<FmsListResponse> itemModel = await _fmsRepository.fetchAllFms();
      _fmsFetcher.sink.add(itemModel);
    } catch (e) {
      _fmsFetcher.sink.addError(e);
    }
  }

  dispose() {
    _fmsFetcher.close();
  }
}
...