8

In flutter we make use of the StreamBuilder with receives a Stream e gives us a Snapshot object that contains "data" but also contains "error" objects.

I want to make a function with async* that yields data but due to some conditions it can yield also some errors. How can I achieve that in Dart?

Stream<int> justAFunction() async* {
  yield 0;

  for (var i = 1; i < 11; ++i) {
    await Future.delayed(millis(500));
    yield i;
  }

  yield AnyError(); <- I WANT TO YIELD THIS!
}

And then, in the StreamBuilder:

StreamBuilder(
            stream: justAFunction(),
            builder: (BuildContext context, AsyncSnapshot<RequestResult> snapshot) {
              return Center(child: Text("The error tha came: ${snapshot.error}")); <- THIS SHOULD BE THE AnyError ABOVE!
            },
          )
Daniel Oliveira
  • 8,053
  • 11
  • 40
  • 76

2 Answers2

12

Simply throw

Stream<int> foo() async* {
  throw FormatException();
}
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • I was about to answer myself but you were faster than me... hahaha. Thank you Rémi :) – Daniel Oliveira Feb 19 '19 at 15:24
  • This seems to work, but the debugger treats it like unhandled exception. Weird. – szotp Jul 31 '19 at 18:28
  • 2
    @Rémi Rousselet, when stream is used in StreamBuilder and exception is raised then debugger stops on `throw` row and treats it as unhandled exception, Weird. – BambinoUA Jun 09 '21 at 07:58
  • Note that throwing from your generator will stop the generator. If you have a stream that performs something in a loop and sometimes wants to report an error, do NOT throw, as you will never recover from the error. Instead, `yield* Stream.error()` as described by https://stackoverflow.com/a/68063101/4857310. – nioncode Jul 07 '23 at 10:24
3

Below the working example:

void main() {
  justAFunction().listen((i) => print(i), onError: (error) => print(error));
}


Stream<int> justAFunction() async* {
  yield 0;

  for (var i = 1; i < 3; ++i) {
    await Future.delayed(Duration(milliseconds:500));
    yield i;
  }

  yield* Stream.error('error is here'); <- Yield error!
}
BambinoUA
  • 6,126
  • 5
  • 35
  • 51