Repository: aome510/spotify-player (language: rust)

Issue:
Random hangs on Raspberry Pi
**Describe the bug**
The app will randomly hang and become completely unresponsive within about 10 seconds of starting. This doesn't always happen - it will either load and run fine indefinitely, or crash within a short time. It continues to consume similar CPU resources to when it was running before the crash. I have some sense that it might be something to do with the console interaction, specifically the fact I'm running it on a relatively small console window.

**To Reproduce**
So far I haven't been able to reproduce this behaviour on app running on x64 Ubuntu, but continues to happen even after clearing cache and recompiling on the Raspberry Pi. It happens randomly when a song is playing, and doesn't seem to be triggered by any specific action.

**Log and backtrace**

Backtrace:

```
Got a panic: PanicInfo {
    payload: Any { .. },
    message: Some(
        Ratio should be between 0 and 1 inclusively.,
    ),
    location: Location {
        file: "/home/pi/.cargo/registry/src/index.crates.io-1cd66030c949c28d/ratatui-0.23.0/src/widgets/gauge.rs",
        line: 62,
        col: 9,
    },
    can_unwind: true,
}

Stack backtrace:
   0: backtrace::backtrace::trace
   1: backtrace::capture::Backtrace::new
   2: spotify_player::init_logging::{{closure}}
   3: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/alloc/src/boxed.rs:2021:9
      std::panicking::rust_panic_with_hook
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/std/src/panicking.rs:711:13
   4: std::panicking::begin_panic_handler::{{closure}}
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/std/src/panicking.rs:597:13
   5: std::sys_common::backtrace::__rust_end_short_backtrace
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/std/src/sys_common/backtrace.rs:170:18
   6: rust_begin_unwind
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/std/src/panicking.rs:595:5
   7: core::panicking::panic_fmt
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/panicking.rs:67:14
   8: ratatui::widgets::gauge::Gauge::ratio
   9: spotify_player::ui::playback::render_playback_window
  10: spotify_player::ui::render_application
  11: ratatui::terminal::Terminal<B>::draw
  12: spotify_player::ui::run
  13: tokio::runtime::task::core::Core<T,S>::poll
  14: tokio::runtime::task::harness::Harness<T,S>::poll
  15: std::sys_common::backtrace::__rust_begin_short_backtrace
  16: core::ops::function::FnOnce::call_once{{vtable.shim}}
  17: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/alloc/src/boxed.rs:2007:9
      <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/alloc/src/boxed.rs:2007:9
      std::sys::unix::thread::Thread::new::thread_start
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/std/src/sys/unix/thread.rs:108:17
```


**Environment**

- OS: Raspberry Pi OS 32 bit (October 10th 2023 version) running on Raspberry Pi 3
- Application version: 0.15.2
- Application features: installed with `cargo install spotify_player`



Discussion / hints:
I've managed to fix the crash by adding a clamp to the ratio in render_playback_progress_bar, e.g.:

```
fn render_playback_progress_bar(
    frame: &mut Frame,
    state: &SharedState,
    ui: &mut UIStateGuard,
    progress: chrono::Duration,
    track: &rspotify_model::FullTrack,
    rect: Rect,
) {
    // Calculate the ratio and clamp it between 0 and 1
    let ratio = (progress.num_seconds() as f64 / track.duration.num_seconds() as f64)
        .clamp(0.0, 1.0);

    match state.app_config.progress_bar_type {
        config::ProgressBarType::Line => frame.render_widget(
            LineGauge::default()
                .gauge_style(ui.theme.playback_progress_bar())
                .ratio(ratio) // Updated to use clamped ratio
                .label(Span::styled(
```
However, the source of the problem is that negative numbers are coming in from progress.num_seconds() (and possibly track.duration.num_seconds()), not sure why.
> I've managed to fix the crash by adding a clamp to the ratio in render_playback_progress_bar, e.g.:
> 
> ```
> fn render_playback_progress_bar(
>     frame: &mut Frame,
>     state: &SharedState,
>     ui: &mut UIStateGuard,
>     progress: chrono::Duration,
>     track: &rspotify_model::FullTrack,
>     rect: Rect,
> ) {
>     // Calculate the ratio and clamp it between 0 and 1
>     let ratio = (progress.num_seconds() as f64 / track.duration.num_seconds() as f64)
>         .clamp(0.0, 1.0);
> 
>     match state.app_config.progress_bar_type {
>         config::ProgressBarType::Line => frame.render_widget(
>             LineGauge::default()
>                 .gauge_style(ui.theme.playback_progress_bar())
>                 .ratio(ratio) // Updated to use clamped ratio
>                 .label(Span::styled(
> ```
> 
> However, the source of the problem is that negative numbers are coming in from progress.num_seconds() (and possibly track.duration.num_seconds()), not sure why.

Hmm, interesting, can you make a PR for the change if it fixes your problem?

Fix patch:
diff --git a/spotify_player/src/ui/playback.rs b/spotify_player/src/ui/playback.rs
index 67173267..84030c12 100644
--- a/spotify_player/src/ui/playback.rs
+++ b/spotify_player/src/ui/playback.rs
@@ -228,11 +228,16 @@ fn render_playback_progress_bar(
     track: &rspotify_model::FullTrack,
     rect: Rect,
 ) {
+    // Negative numbers can sometimes appear from progress.num_seconds() so this stops
+    // them coming through into the ratios
+    let ratio =
+        (progress.num_seconds() as f64 / track.duration.num_seconds() as f64).clamp(0.0, 1.0);
+
     match state.app_config.progress_bar_type {
         config::ProgressBarType::Line => frame.render_widget(
             LineGauge::default()
                 .gauge_style(ui.theme.playback_progress_bar())
-                .ratio(progress.num_seconds() as f64 / track.duration.num_seconds() as f64)
+                .ratio(ratio)
                 .label(Span::styled(
                     format!(
                         "{}/{}",
@@ -246,7 +251,7 @@ fn render_playback_progress_bar(
         config::ProgressBarType::Rectangle => frame.render_widget(
             Gauge::default()
                 .gauge_style(ui.theme.playback_progress_bar())
-                .ratio(progress.num_seconds() as f64 / track.duration.num_seconds() as f64)
+                .ratio(ratio)
                 .label(Span::styled(
                     format!(
                         "{}/{}",


Test patch: