简体   繁体   English

为什么子窗口小部件StreamBuilders没有收到错误?

[英]Why are child widget StreamBuilders not receiving errors?

I am struggling with RxDart (maybe just straight up Rx programming). 我正在努力与RxDart(也许只是直接Rx编程)。 I currently have a stateful widget that calls my bloc in it's didChangeDependencies() . 我目前有一个有状态的小部件,在它的didChangeDependencies()中调用我的bloc。 That call goes out and gets data via http request and adds it to a stream. 该呼叫通过http请求发出并获取数据并将其添加到流中。 I'm using BehaviorSubject and this works fine. 我正在使用BehaviorSubject ,这很好用。 I have child widgets using StreamBuilders and they get data no problem. 我有使用StreamBuilders的子窗口小部件,他们得到的数据没问题。 My issue comes in dealing with errors. 我的问题在于处理错误。 If my http request fails, I hydrate the stream with addError('whatever error') but my child widget's StreamBuilder is not receiving that error. 如果我的http请求失败,我使用addError('whatever error')流,但我的子窗口小部件的StreamBuilder没有收到该错误。 It doesn't get anything at all. 它什么都没有得到。

So I have a few questions. 所以我有几个问题。

  1. Is that expected? 这是预期的吗?
  2. Should error handling not be done in StreamBuilder? 是否应该在StreamBuilder中进行错误处理? Ideally, I want to show something in the UI if something goes wrong so not sure how else to do it. 理想情况下,如果出现问题,我想在UI中显示一些内容,因此不确定如何做到这一点。
  3. I could make my child widget stateful and use stream.listen . 我可以使我的子窗口小部件有状态并使用stream.listen I do receive the errors there but it seems like overkill to have that and the StreamBuilder. 我确实收到了那里的错误但是看起来有点过分和StreamBuilder。
  4. Am I missing something fundamental here about streams and error handling? 我是否遗漏了关于流和错误处理的基本内容?

Here is my bloc: 这是我的集团:

final _plans = BehaviorSubject<List<PlanModel>>();
Observable<List<PlanModel>> get plans => _plans.stream;

fetchPlans() async {
    try {
        final _plans = await _planRepository.getPlans();
        _plans.add(_plans);
    }
    on AuthenticationException {
        _plans.addError('authentication error');
    }
    on SocketException {
        _plans.addError('no network connection');
    }
    catch(error) {
        _plans.addError('fetch unsuccessful');
    }
}

Simplified Parent Widget: 简化的父窗口小部件:

class PlanPage extends StatefulWidget {
  @override
  PlanPageState createState() {
    return new PlanPageState();
  }
}

class PlanPageState extends State<PlanPage> {

  @override
  void didChangeDependencies() async {
    super.didChangeDependencies();
    var planBloc = BaseProvider.of<PlanBloc>(context);
    planBloc.fetchPlans();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar( title: const Text('Your Plan') ),
        body: PlanWrapper()
    );
  }
}

Simplified Child Widget with StreamBuilder: StreamBuilder的简化子窗口小部件:

class PlanWrapper extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    var planBloc = BaseProvider.of<PlanBloc>(context);

    return StreamBuilder(
      stream: planBloc.plans,
      builder: (BuildContext context, AsyncSnapshot<List<PlanModel>> plans) {
        if (plans.hasError) {
          //ERROR NEVER COMES IN HERE
          switch(plans.error) {
            case 'authentication error':
              return RyAuthErrorCard();
            case 'no network connection':
              return RyNetworkErrorCard();
            default: 
              return RyGenericErrorCard(GeneralException().errorMessages()['message']);
          }
        }
        if (plans.hasData && plans.data.isNotEmpty) {
          return ListView(
            physics: const AlwaysScrollableScrollPhysics(),
            children: _buildPlanTiles(context, plans.data)
          );
        }
        return Center(child: const CircularProgressIndicator());
      }
    );
  }
}

There was an issue about this in the RxDart GitHub ( https://github.com/ReactiveX/rxdart/issues/227 ). 在RxDart GitHub中有一个问题( https://github.com/ReactiveX/rxdart/issues/227 )。 BehaviorSubjects were not replaying errors to new listeners. BehaviorSubjects没有向新侦听器重放错误。

It was fixed in version 0.21.0. 它在版本0.21.0中得到修复。 "Breaking Change: BehaviorSubject will now emit an Error, if the last event was also an Error. Before, when an Error occurred before a listen, the subscriber would not be notified of that Error." “破坏更改:如果最后一个事件也是错误,则BehaviorSubject现在将发出错误。之前,当在侦听之前发生错误时,将不会通知订户该错误。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM