bugsnag / bugsnag-flutter

BugSnag crash reporting for Flutter apps
https://docs.bugsnag.com/platforms/flutter/
MIT License
11 stars 11 forks source link

Calling .first on an empty List causes a StateError #186

Closed msisinni closed 1 year ago

msisinni commented 1 year ago

By far the most common error getting reported for my app is a StateError. This overwhelmingly happens on iOS, and very rarely happens on Android (at a ratio of approximately 250 errors on iOS to 1 on Android). This error gets reported so frequently that bugsnag has rate limited errors from my app. This has been happening for months across multiple versions of Flutter.

Here's an example of the error:

``` StateError Bad state: No element #0 _GrowableList.first (dart:core-patch/growable_array.dart:343) #1 ChannelClient._createEvent (package:bugsnag_flutter/src/client.dart:526) #2 ChannelClient._notifyInternal (package:bugsnag_flutter/src/client.dart:479) #3 ChannelClient._onFlutterError (package:bugsnag_flutter/src/client.dart:466) #4 FlutterError.reportError (package:flutter/src/foundation/assertions.dart:1184) #5 ImageStreamCompleter.reportError (package:flutter/src/painting/image_stream.dart:733) #6 MultiFrameImageStreamCompleter. (package:flutter/src/painting/image_stream.dart:862) #7 _RootZone.runBinary (dart:async/zone.dart:1658) #8 _FutureListener.handleError (dart:async/future_impl.dart:162) #9 Future._propagateToListeners (dart:async/future_impl.dart:778) #10 Future._propagateToListeners (dart:async/future_impl.dart:799) #11 Future._completeError (dart:async/future_impl.dart:574) #12 _completeOnAsyncError (dart:async-patch/async_patch.dart:318) #13 _RootZone.runBinary (dart:async/zone.dart:1658) #14 _FutureListener.handleError (dart:async/future_impl.dart:162) #15 Future._propagateToListeners (dart:async/future_impl.dart:778) #16 Future._propagateToListeners (dart:async/future_impl.dart:799) #17 Future._completeError (dart:async/future_impl.dart:574) #18 Future.wait (dart:async/future.dart:507) #19 _RootZone.runBinary (dart:async/zone.dart:1658) #20 _FutureListener.handleError (dart:async/future_impl.dart:162) #21 Future._propagateToListeners (dart:async/future_impl.dart:778) #22 Future._propagateToListeners (dart:async/future_impl.dart:799) #23 Future._completeError (dart:async/future_impl.dart:574) #24 Future._chainForeignFuture (dart:async/future_impl.dart:519) #25 _microtaskLoop (dart:async/schedule_microtask.dart:40) #26 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49) ```

This error comes from the following line in the bugsnag_flutter library: https://github.com/bugsnag/bugsnag-flutter/blob/f2a34037cd284506bd58d24c033ea60cdb25a30e/packages/bugsnag_flutter/lib/src/client.dart#L526 error.stacktrace happens to be empty, so calling .first will throw a StateError.

I forked the bugsnag_flutter repo and fixed that line. I don't know why error.stacktrace is empty, but I have an idea of the order of events that leads to the StateError.

Since releasing a new version of my app with the forked repo yesterday, it has always happened because of an HttpException. Nearly all of those HttpExceptions were from a request for an image via network either timing out (HttpException Operation timed out) or having its connection closed (HttpException Connection closed before full header was received). The HttpException then gets sent to bugsnag for error reporting, and then bugsnag throws a StateError because of the line I mentioned.

I'm going to make a pull request with the fix I made in my forked repo.

msisinni commented 1 year ago

Here's the PR I made https://github.com/bugsnag/bugsnag-flutter/pull/187

msisinni commented 1 year ago

Here's an example of one of the errors after using my forked repo. It looks like not having a stacktrace is an acceptable outcome that gets handled a special way in bugsnag error reports. That points more to the line I mentioned above being an incorrect use of .first.

Screen Shot 2022-12-09 at 12 04 05 PM
johnkiely1 commented 1 year ago

Hi @msisinni. Thanks for reporting this and the related PR. We're going to do some investigation around why the stacktrace is empty. We will update here as soon as we can.

johnkiely1 commented 1 year ago

Hi @msisinni, a fix for this was released in v2.5.0.