在返回Stream的函数中实现异常处理

时间:2013-03-29 10:06:55

标签: asynchronous dart

我正在实现一个返回Stream的函数。我不确定如何实现错误处理,最佳做法是什么?

对于返回Future的函数,最佳做法是never to throw a synchronous error。对于返回Stream的函数也是如此吗?

这是我正在思考的一个例子:

Stream<int> count() {
   var controller = new StreamController<int>();
   int i = 0;
   try {
     doSomethingThatMightThrow();
     new Timer.repeating(new Duration(seconds: 1), () => controller.add(i++));
   } on Exception catch (e) {
     controller.addError(e);
     controller.close();
   }
   return controller.stream;
}

2 个答案:

答案 0 :(得分:2)

一般来说,Streams也是如此。主要思想是,用户只需要以一种方式处理错误。您的示例将所有错误移至流中。

在某些情况下,即时错误更好(例如,您可能会因为编程错误而导致错误,并且永远不应该处理,或者如果您想保证Stream永远不会产生错误),但是发送错误通过溪流几乎总是一件好事。

小尼特:在某人开始收听之前,流通常(有例外)不会产生任何数据。在你的例子中,你正在启动一个Timer,即使你甚至不知道是否会有一个监听器。我猜这个例子已经减少了,并没有代表你真正的代码,但它是值得注意的。解决方案是使用StreamController的回调进行暂停和订阅更改。

答案 1 :(得分:1)

我已经更新了这个例子,以接受弗洛里安的评论。

在我的实际用例中,我不想缓冲结果,所以如果流暂停,我会抛出UnsupportedError。

我已经把它作为终止流而不是无限流。

如果此函数的用户在几秒钟后异步添加一个侦听器,那么它们将丢失前几个结果。他们不应该这样做。我想这是要清楚记录的东西。虽然也许,如果订阅状态在收到第一个数据后但在收到关闭之前发生变化,我也会抛出错误。

Stream<int> count(int max) {
   var controller = new StreamController<int>(
           onPauseStateChange: () => throw new UnsupportedError('count() Stream pausing not supported.'));
   int i = 0;
   try {
     doSomethingThatMightThrow();
     new Timer.repeating(new Duration(seconds: 1), () {
        if (!controller.hasSubscribers)
           return;
        controller.add(i++);
        if (i >= max)
           controller.close();
     });
   } on Exception catch (e) {
     controller.addError(e);
     controller.close();
   }
   return controller.stream;
}