tung
tung

Reputation: 769

How to catch Errors thrown in onData Methods of stream.listen

I'm building an Event driven application with Dart.

Therefor I have one central stream where all Events are put on.

class EventManager {
  final StreamController<Event> _dataStreamController =
      StreamController<Event>.broadcast();

  Stream get stream => _dataStreamController.stream;

  void addEvent(event) {
    _dataStreamController.sink.add(event);
  }
}

Is there a way to catch all Errors that are thrown during the onData Method of all the listens on my central Stream in one place.

Sample of a listen and its onData Method(handleMyEvent):

eventManager.stream
        .where((event) => event is MyEvent)
        .listen(handleMyEvent);

 void handleMyEvent(event) {
    //handles MyEvent
    //might throw an Error
    throw Errror();
 }

Or would every onData Method(handleMyEvent) need it's own try catch block like this:

 void handleMyEvent(event) {
    try{
      //handles MyEvent
      //might throw an Error
    } catch (generalError) {
      //handle Error
    }
 }

because it's not possible to catch it in a central place?

Upvotes: 4

Views: 777

Answers (1)

lrn
lrn

Reputation: 71828

If the onData handler throws, it becomes an uncaught asynchronous error. There is no surrounding context to catch that error, and nowhere to forward it to.

The only way to catch those errors is to introduce an uncaught error handler in the zone where the onData handler is run. Example:

runZonedGuarded(() {
  stream.listen((event) {
    mayThrow(event);
  });
}, (e, s) {
  log(e, s); // or whatever.
});

If you use stream.forEach(onDataHandler) instead, then the handler throwing will terminate the forEach and the error will be reported in the returned future. I recommend always using forEach over listen unless you need access to the stream subscription returned by listen, or need to handle error events instead of just stopping at the first one.

Upvotes: 5

Related Questions