如何使用 StreamBuilder 管理块抛出的异常?
How to manage blocs thrown exceptions with StreamBuilder?
当我的提供商在 http.get()
调用期间出现问题时,我正在尝试 return 将快照错误状态发送到我的 StreamBuilder。在我的例子中,当 http.get()
return 的状态不同于 200 (OK) 时,我抛出异常。
我希望能够 return 对错误状态进行快照并针对这种情况执行特定代码。
现在,当我抛出异常时,应用程序就会崩溃。
提供商:
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');
}
}
}
存储库:
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();
})
当抛出异常时,我想获取一个快照错误,然后在我的页面中只可视化一个文本。
您应该将 api 调用包装在 try catch 中,然后将错误添加到接收器。
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();
}
}
标记为正确的答案对我不起作用。进行一些调试后,我发现问题出在 catch/throw 中:即使您在调试控制台中看到异常,您实际上也不会去那里。
对我来说,在 Debug 中,应用程序不会崩溃,但会在 Exception 上有一个断点,您可以使用“播放”按钮继续播放它。相反,使用 运行 按钮,您可以在没有断点的情况下获得相同的行为(就像真实用户一样)。
这是我的 BLoC 实现的流程:http 调用 -> 提供者 -> 存储库 -> bloc -> ui.
我试图处理丢失互联网连接的情况,但没有检查它并处理一般错误情况。
我的证据是提供程序中的 throw Exception ('Error'); 不会传播到流的右侧。我还尝试了 try/catch 等其他方法,并将它们应用于代码中的不同级别。
基本上我需要实现的是调用 fetcher.sink.addError('Error');但是从发生错误的提供程序内部。然后检查 UI 中的 snapshot.hasError 将 return 为真,并且错误很容易处理。
这是唯一对我有用的(丑陋的)东西:将接收器对象作为输入提供给提供者本身的调用,并在 http 调用的 onCatchError() 函数中将错误添加到通过它的功能下沉。
我希望它对某人有用。我知道这实际上不是最佳实践,但我只需要一个 quick-and-dirty 解决方案。如果谁有更好的solution/explanation,我会欣然阅读评论
当我的提供商在 http.get()
调用期间出现问题时,我正在尝试 return 将快照错误状态发送到我的 StreamBuilder。在我的例子中,当 http.get()
return 的状态不同于 200 (OK) 时,我抛出异常。
我希望能够 return 对错误状态进行快照并针对这种情况执行特定代码。
现在,当我抛出异常时,应用程序就会崩溃。
提供商:
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');
}
}
}
存储库:
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();
})
当抛出异常时,我想获取一个快照错误,然后在我的页面中只可视化一个文本。
您应该将 api 调用包装在 try catch 中,然后将错误添加到接收器。
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();
}
}
标记为正确的答案对我不起作用。进行一些调试后,我发现问题出在 catch/throw 中:即使您在调试控制台中看到异常,您实际上也不会去那里。
对我来说,在 Debug 中,应用程序不会崩溃,但会在 Exception 上有一个断点,您可以使用“播放”按钮继续播放它。相反,使用 运行 按钮,您可以在没有断点的情况下获得相同的行为(就像真实用户一样)。
这是我的 BLoC 实现的流程:http 调用 -> 提供者 -> 存储库 -> bloc -> ui.
我试图处理丢失互联网连接的情况,但没有检查它并处理一般错误情况。
我的证据是提供程序中的 throw Exception ('Error'); 不会传播到流的右侧。我还尝试了 try/catch 等其他方法,并将它们应用于代码中的不同级别。
基本上我需要实现的是调用 fetcher.sink.addError('Error');但是从发生错误的提供程序内部。然后检查 UI 中的 snapshot.hasError 将 return 为真,并且错误很容易处理。
这是唯一对我有用的(丑陋的)东西:将接收器对象作为输入提供给提供者本身的调用,并在 http 调用的 onCatchError() 函数中将错误添加到通过它的功能下沉。
我希望它对某人有用。我知道这实际上不是最佳实践,但我只需要一个 quick-and-dirty 解决方案。如果谁有更好的solution/explanation,我会欣然阅读评论