From 69b8f29f880712efb8135d116118532b44b96d97 Mon Sep 17 00:00:00 2001 From: Dustin Date: Tue, 4 Aug 2026 16:47:58 +0200 Subject: [PATCH] =?UTF-8?q?v2.49.6=20=E2=80=94=20Async-Exceptions=20abgesi?= =?UTF-8?q?chert=20(kein=20Crash=20bei=20nicht-seekbaren=20Quellen)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Fix (Code-Review Finding 4, MED) - PlayerService.play/playPause/pause/seek: try/catch mit MeloLogger — schützt ALLE Aufrufer (Buttons, Listener, System-Controls) - naechstes: Repeat-Titel-Zweig (seek+play) try/catch — Live-Streams ohne Seek-Unterstützung crashen nicht mehr - vorheriges: kompletter Ablauf try/catch (Seek-Pfad + Songwechsel) - NowPlayingScreen: Lyrics-Tap + Slider-Seek laufen über die abgesicherte seek()-Methode — keine unhandled async Exceptions aus Fire-and-Forget --- lib/services/player_service.dart | 84 ++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/lib/services/player_service.dart b/lib/services/player_service.dart index d7aa808..6c979c0 100644 --- a/lib/services/player_service.dart +++ b/lib/services/player_service.dart @@ -160,59 +160,91 @@ class PlayerService extends ChangeNotifier { Future playPause() async { if (_player == null) return; - if (_p.playing) { - await _p.pause(); - } else if (aktuellerSong != null) { - await _p.play(); + try { + if (_p.playing) { + await _p.pause(); + } else if (aktuellerSong != null) { + await _p.play(); + } + } catch (e) { + debugPrint('Play/Pause fehlgeschlagen: $e'); + MeloLogger().fehler('player_playpause', e); } } /// Explizit abspielen (kein Toggle) — für System-Controls (Bluetooth, etc.) Future play() async { if (_player == null || aktuellerSong == null) return; - await _p.play(); + try { + await _p.play(); + } catch (e) { + debugPrint('Play fehlgeschlagen: $e'); + MeloLogger().fehler('player_play', e); + } } /// Explizit pausieren (kein Toggle) — für System-Controls (Bluetooth, etc.) Future pause() async { if (_player == null) return; - await _p.pause(); + try { + await _p.pause(); + } catch (e) { + debugPrint('Pause fehlgeschlagen: $e'); + MeloLogger().fehler('player_pause', e); + } } /// Nur seeken ohne Reload der Quelle Future seek(Duration position) async { if (_player == null) return; - await _p.seek(position); + try { + await _p.seek(position); + } catch (e) { + // Live-Streams ohne Seek-Unterstützung werfen hier — nicht crashen + debugPrint('Seek fehlgeschlagen: $e'); + MeloLogger().fehler('player_seek', e); + } } Future vorheriges() async { if (_player == null || aktuellerSong == null) return; - final pos = _p.position; - if (pos.inSeconds > 5) { - await _p.seek(Duration.zero); - return; - } - if (_zufallsmodus && _shuffleReihenfolge.isNotEmpty) { - _shufflePos--; - if (_shufflePos < 0) _shufflePos = 0; - final idx = _shuffleReihenfolge[_shufflePos]; - if (idx >= 0 && idx < _warteschlange.length) { - await spiele(_warteschlange[idx]); + try { + final pos = _p.position; + if (pos.inSeconds > 5) { + await _p.seek(Duration.zero); + return; } - return; - } - final neuerIndex = _aktuellerIndex - 1; - if (neuerIndex >= 0) { - await spiele(_warteschlange[neuerIndex]); + if (_zufallsmodus && _shuffleReihenfolge.isNotEmpty) { + _shufflePos--; + if (_shufflePos < 0) _shufflePos = 0; + final idx = _shuffleReihenfolge[_shufflePos]; + if (idx >= 0 && idx < _warteschlange.length) { + await spiele(_warteschlange[idx]); + } + return; + } + final neuerIndex = _aktuellerIndex - 1; + if (neuerIndex >= 0) { + await spiele(_warteschlange[neuerIndex]); + } + } catch (e) { + debugPrint('Vorheriger Song fehlgeschlagen: $e'); + MeloLogger().fehler('player_vorheriges', e); } } Future naechstes() async { if (_player == null || aktuellerSong == null) return; if (_wiederholmodus == Wiederholmodus.titel) { - // Gleichen Song von vorn wiederholen - await _p.seek(Duration.zero); - await _p.play(); + // Gleichen Song von vorn wiederholen — seek/play können bei nicht + // seekbaren Quellen (Live-Streams) werfen, daher abgesichert. + try { + await _p.seek(Duration.zero); + await _p.play(); + } catch (e) { + debugPrint('Repeat-Titel fehlgeschlagen: $e'); + MeloLogger().fehler('player_repeat_titel', e); + } return; } final idx = naechsterIndex();