nt4f04uNd / sweyer

Music player built with Flutter
BSD 3-Clause "New" or "Revised" License
197 stars 47 forks source link

Hangs on startup due to missing album metadata #122

Closed Abestanis closed 3 months ago

Abestanis commented 3 months ago

Steps to reproduce

  1. Have some music with missing metadata. Probably a missing year, but I haven't found out which song is the culprit.

Either

  1. Update to the latest version.
  2. Start the app.
  3. Get stuck on the splash screen forever.

Or

  1. Freshly install the latest version.
  2. Open the app.
  3. Grant permissions.
  4. Get stuck forever searching for music.

What did you expect?

For the app to start.

What happened instead?

We just hang forever because we throw an exception here https://github.com/nt4f04uNd/sweyer/blob/7496517cb5572b1e00ce3ac572bbde2a62e30b11/lib/logic/models/album.dart#L103 and here https://github.com/nt4f04uNd/sweyer/blob/7496517cb5572b1e00ce3ac572bbde2a62e30b11/lib/logic/models/album.dart#L104

The value for fistYear and lastYear seem to be null for at least one album, so the cast to int fails.

We should:

I would love to submit a MR so we can patch this as soon as possible (I think this deserves a hot fix release), but I'm on vacation for a week so I won't be able to work on it until I'm back.

Sweyer version

1.0.10

Android version

14

Abestanis commented 3 months ago

Also, I'm wondering if you saw these exceptions in Fire ase.

nt4f04uNd commented 3 months ago

@Abestanis I added you as a viewer to the Firebase project

nt4f04uNd commented 3 months ago

I do see a few exceptions there

nt4f04uNd commented 3 months ago

I uploaded the debug symbols, and new crashes should automatically be deobfuscated for this version

Made an issue to automate it https://github.com/nt4f04uNd/sweyer/issues/123

nt4f04uNd commented 3 months ago

Deobfuscated stacktrace

          Non-fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: type 'Null' is not a subtype of type 'int' in type cast
#00 pc 0x3fe127 com.nt4f04und.sweyer (new Album.fromMap [album.dart:103]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#01 pc 0x3fdee3 com.nt4f04und.sweyer (Album.Album.fromMap [album.dart:96]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#02 pc 0x6d0d7b com.nt4f04und.sweyer (SweyerPlugin.retrieveAlbums [sweyer_plugin.dart:82]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#03 pc 0x690b6b com.nt4f04und.sweyer (_SuspendState._createAsyncStarCallback.<anonymous closure> [async_patch.dart:353]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#04 pc 0x69626b com.nt4f04und.sweyer (_rootRunUnary [zone.dart:1406]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#05 pc 0x1bfc13 com.nt4f04und.sweyer (_rootRunUnary [zone.dart:1404]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#06 pc 0x1bffb7 com.nt4f04und.sweyer (_FutureListener.handleValue [zone.dart:1307]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#07 pc 0x6964c7 com.nt4f04und.sweyer (Future._propagateToListeners.handleValueCallback [future_impl.dart:767]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#08 pc 0x1bed3b com.nt4f04und.sweyer (Future._propagateToListeners [future_impl.dart:796]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#09 pc 0x1c3d97 com.nt4f04und.sweyer (Future._completeWithValue [future_impl.dart:567]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#10 pc 0x69117b com.nt4f04und.sweyer (_SuspendState._returnAsync [async_patch.dart:324]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#11 pc 0x690b6b com.nt4f04und.sweyer (_SuspendState._createAsyncStarCallback.<anonymous closure> [async_patch.dart:353]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#12 pc 0x69626b com.nt4f04und.sweyer (_rootRunUnary [zone.dart:1406]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#13 pc 0x1bfc13 com.nt4f04und.sweyer (_rootRunUnary [zone.dart:1404]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#14 pc 0x1bffb7 com.nt4f04und.sweyer (_FutureListener.handleValue [zone.dart:1307]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#15 pc 0x6964c7 com.nt4f04und.sweyer (Future._propagateToListeners.handleValueCallback [future_impl.dart:767]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#16 pc 0x1bed3b com.nt4f04und.sweyer (Future._propagateToListeners [future_impl.dart:796]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#17 pc 0x1c3d97 com.nt4f04und.sweyer (Future._completeWithValue [future_impl.dart:567]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#18 pc 0x69117b com.nt4f04und.sweyer (_SuspendState._returnAsync [async_patch.dart:324]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#19 pc 0x690b6b com.nt4f04und.sweyer (_SuspendState._createAsyncStarCallback.<anonymous closure> [async_patch.dart:353]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#20 pc 0x69626b com.nt4f04und.sweyer (_rootRunUnary [zone.dart:1406]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#21 pc 0x1bfc13 com.nt4f04und.sweyer (_rootRunUnary [zone.dart:1404]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#22 pc 0x1bffb7 com.nt4f04und.sweyer (_FutureListener.handleValue [zone.dart:1307]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#23 pc 0x6964c7 com.nt4f04und.sweyer (Future._propagateToListeners.handleValueCallback [future_impl.dart:767]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#24 pc 0x1bed3b com.nt4f04und.sweyer (Future._propagateToListeners [future_impl.dart:796]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#25 pc 0x1c3d97 com.nt4f04und.sweyer (Future._completeWithValue [future_impl.dart:567]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#26 pc 0x69117b com.nt4f04und.sweyer (_SuspendState._returnAsync [async_patch.dart:324]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#27 pc 0x690b6b com.nt4f04und.sweyer (_SuspendState._createAsyncStarCallback.<anonymous closure> [async_patch.dart:353]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#28 pc 0x69626b com.nt4f04und.sweyer (_rootRunUnary [zone.dart:1406]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#29 pc 0x1bfc13 com.nt4f04und.sweyer (_rootRunUnary [zone.dart:1404]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#30 pc 0x1bffb7 com.nt4f04und.sweyer (_FutureListener.handleValue [zone.dart:1307]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#31 pc 0x6964c7 com.nt4f04und.sweyer (Future._propagateToListeners.handleValueCallback [future_impl.dart:767]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#32 pc 0x1bed3b com.nt4f04und.sweyer (Future._propagateToListeners [future_impl.dart:796]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#33 pc 0x1c3d97 com.nt4f04und.sweyer (Future._completeWithValue [future_impl.dart:567]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#34 pc 0x1c093b com.nt4f04und.sweyer (Future._asyncCompleteWithValue.<anonymous closure> [future_impl.dart:640]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#35 pc 0x696a1f com.nt4f04und.sweyer (_rootRun [zone.dart:1398]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#36 pc 0x1c016f com.nt4f04und.sweyer (_rootRun [zone.dart:1389]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#37 pc 0x5fcee7 com.nt4f04und.sweyer (_CustomZone.run [zone.dart:1300]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#38 pc 0x7114fb com.nt4f04und.sweyer (_CustomZone.runGuarded [zone.dart:1208]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#39 pc 0x5fd28f com.nt4f04und.sweyer (_CustomZone.bindCallbackGuarded.<anonymous closure> [zone.dart:1248]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#40 pc 0x1be40b com.nt4f04und.sweyer (_microtaskLoop [schedule_microtask.dart:40]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#41 pc 0x69553b com.nt4f04und.sweyer (_startMicrotaskLoop [schedule_microtask.dart:49]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
#42 pc 0x1be37f com.nt4f04und.sweyer (_startMicrotaskLoop [schedule_microtask.dart:44]) (BuildId: bca64abfc060cd5531bb8f1c719e3625)
nt4f04uNd commented 3 months ago

I'm wondering what's changed in the last version that it started failing

nt4f04uNd commented 3 months ago

Interestingly enough, I bisected to this commit https://github.com/nt4f04uNd/sweyer/commit/3398b4e7acf1dec3ff6935253278bbb24eef0c45

nt4f04uNd commented 3 months ago

Seemingly, it's a broken Youtube metadata

image

Apparently, we'll need to make it nullable

UPD: Oh not, it's just a name of some random album on my device :-) Still don't understand why it worked in the past, but ok

Abestanis commented 3 months ago

Interestingly enough, I bisected to this commit 3398b4e

I'll try to investigate that when I'm back from holidays.

Abestanis commented 3 months ago

Interestingly enough, I bisected to this commit https://github.com/nt4f04uNd/sweyer/commit/3398b4e7acf1dec3ff6935253278bbb24eef0c45

I couldn't verify it, but I think the reason why this has not been a problem before is that the Cursor.getInt call here must have returned 0 for NULL: https://github.com/nt4f04uNd/sweyer/blob/010337163fc033b9330c5fcc4d072a57fdc0132f/sweyer_plugin/android/src/main/java/com/nt4f04und/sweyer/sweyer_plugin/handlers/FetchHandler.java#L181

Cursor.getInt documentation

In Kotlin, that call was throwing an exception, which is why we added this null check here: https://github.com/nt4f04uNd/sweyer/blob/d40944298502db1e6e84771d63f9b629d68e9da9/sweyer_plugin/android/src/main/kotlin/com/nt4f04und/sweyer/sweyer_plugin/handlers/FetchHandler.kt#L255

So now we were adding null to the map instead of 0.

I think we should probably treat all data except the id coming from the android media database as nullable. What do you think?

nt4f04uNd commented 3 months ago

I think we should probably treat all data except the id coming from the android media database as nullable. What do you think?

This might be tricky to support. I would evauluate whether this is actually the case, because the databases themselves definitely do not have all columns as nullable