Skip to content

fix: prevent panic when selecting difficulty with no challenges#278

Merged
unhappychoice merged 1 commit intomainfrom
feature/fix-empty-repo-panic
Oct 5, 2025
Merged

fix: prevent panic when selecting difficulty with no challenges#278
unhappychoice merged 1 commit intomainfrom
feature/fix-empty-repo-panic

Conversation

@unhappychoice
Copy link
Copy Markdown
Owner

@unhappychoice unhappychoice commented Oct 5, 2025

Closes: #276

Summary

Fix panic that occurs when selecting difficulty on the title screen when repository contains no extractable challenges.

Changes

  • Add validation to check if challenges are available for selected difficulty before transitioning to Typing screen
  • Display error message in red when no challenges are available for the selected difficulty
  • Clear error message when user changes difficulty selection
  • Prevent screen transition when challenge count is 0

Test plan

  • Run cargo check
  • Run cargo test
  • Run cargo clippy --all-targets --all-features -- -D warnings
  • Run cargo fmt

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Validates challenge availability before starting from the Title screen; shows a clear, centered error message if none.
    • Error message clears automatically when changing difficulty or selecting a valid option; normal descriptions return when no error is present.
  • Bug Fixes
    • Prevents starting a session when the selected difficulty has zero available challenges.

- Add validation to check if challenges are available for selected difficulty
- Display error message when no challenges are available
- Clear error message when difficulty is changed
- Prevent transition to Typing screen when challenge count is 0

Closes: #276

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 5, 2025

Walkthrough

Adds error-state handling to TitleScreen when starting a game with no available challenges. Introduces an optional error message, clears it on navigation, validates challenge availability on Space, and passes the message to the difficulty selection view, which conditionally renders the error instead of descriptions. Also updates challenge count initialization.

Changes

Cohort / File(s) Summary
Title screen logic and state
src/presentation/game/screens/title_screen.rs
Added error_message: Option<String>, get_error_message(&self) -> Option<&String>. On Space, validate selected difficulty’s challenge count; set/clear error and control transition accordingly. Clear error on Left/Right. Init updates challenge_counts. Render passes error_message to view.
Difficulty view rendering
src/presentation/game/views/title/difficulty_selection_view.rs
Updated DifficultySelectionView::draw(...) signature to accept error_message: Option<&String>. Conditional rendering: if error, center and style error text; else render existing description lines.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant TitleScreen
  participant StageRepository as Stage Repo
  participant DifficultyView as Difficulty View
  participant Game as Game State

  rect rgb(240,248,255)
    note over TitleScreen: Init
    TitleScreen->>StageRepository: fetch challenge_counts
    StageRepository-->>TitleScreen: counts per difficulty
    TitleScreen->>DifficultyView: draw(..., error_message=None)
  end

  User->>TitleScreen: Left/Right
  TitleScreen->>TitleScreen: update selected_difficulty<br/>clear error_message
  TitleScreen->>DifficultyView: draw(..., error_message=None)

  User->>TitleScreen: Space (Start)
  TitleScreen->>TitleScreen: check challenge_counts[selected]
  alt No challenges
    TitleScreen->>TitleScreen: set error_message = "No challenges..."
    TitleScreen->>DifficultyView: draw(..., error_message=Some)
    TitleScreen-->>User: stay on TitleScreen
  else Has challenges
    TitleScreen->>Game: transition to Typing
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

A hop on the keys, then—whoa! nothing to type,
I twitch my ears: “No challenges here,” the gripe.
Now gentler paths guard every start,
With scarlet whispers if files depart.
When code appears, I bound with glee—
A bunny’s game begins, crash-free! 🐇⌨️

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Linked Issues Check ❓ Inconclusive The PR implements validation to prevent panics, displays an error message when no challenges exist, clears the message on difficulty change, and blocks transitions, addressing the core objectives of issue #276. However, it is not clear from the provided summary whether the error message includes guidance on supported file types or code structures as suggested in the linked issue. Without inspecting the actual error_message content, full compliance with that guidance requirement cannot be confirmed. Confirm that the error_message text provides specific guidance on supported file types or code structures as outlined in issue #276, and if it does not, extend the implementation to include this information so that reviewers can verify compliance.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely describes the main change by stating that the PR fixes a panic when selecting a difficulty level without available challenges. It directly reflects the primary purpose of the modifications without extraneous details or vague terminology. It follows best practices for an informative, single-sentence summary.
Out of Scope Changes Check ✅ Passed All modifications are restricted to the title screen logic and the difficulty selection view to add error handling for empty challenge sets, and the minor update to get_git_repository usage supports this new error flow. No unrelated files or features outside the scope of handling empty repositories have been altered. Thus, there are no out-of-scope changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/fix-empty-repo-panic

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Oct 5, 2025

Codecov Report

❌ Patch coverage is 0% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 24.59%. Comparing base (d311bf6) to head (f3c95e0).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/presentation/game/screens/title_screen.rs 0.00% 17 Missing ⚠️
...tion/game/views/title/difficulty_selection_view.rs 0.00% 14 Missing ⚠️

❌ Your patch status has failed because the patch coverage (0.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project status has failed because the head coverage (24.59%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #278      +/-   ##
==========================================
- Coverage   24.61%   24.59%   -0.03%     
==========================================
  Files         195      195              
  Lines       21720    21743      +23     
==========================================
  Hits         5347     5347              
- Misses      16373    16396      +23     
Files with missing lines Coverage Δ
...tion/game/views/title/difficulty_selection_view.rs 0.00% <0.00%> (ø)
src/presentation/game/screens/title_screen.rs 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/presentation/game/views/title/difficulty_selection_view.rs (1)

21-21: Prefer Option<&str> over Option<&String>.

Using &String is less idiomatic in Rust. &str is more flexible and works with String, &str, and string literals without requiring an intermediate reference.

Apply this diff:

-        error_message: Option<&String>,
+        error_message: Option<&str>,

Also update line 184 in title_screen.rs:

-            self.error_message.as_ref(),
+            self.error_message.as_deref(),
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d311bf6 and f3c95e0.

📒 Files selected for processing (2)
  • src/presentation/game/screens/title_screen.rs (5 hunks)
  • src/presentation/game/views/title/difficulty_selection_view.rs (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/presentation/game/views/title/difficulty_selection_view.rs (2)
src/presentation/ui/colors.rs (2)
  • error (41-43)
  • to_crossterm (163-185)
src/domain/models/difficulty_level.rs (1)
  • description (23-31)
🔇 Additional comments (4)
src/presentation/game/views/title/difficulty_selection_view.rs (1)

79-104: LGTM!

The conditional rendering logic correctly displays error messages when present and falls back to difficulty descriptions otherwise. The error styling (red + bold) provides clear visual feedback to users.

src/presentation/game/screens/title_screen.rs (3)

105-117: LGTM! Validation prevents the panic condition.

The challenge count check correctly prevents screen transition when no challenges are available, addressing the panic issue from #276. The error message is clear and actionable.

Minor observation: The error message is 95 characters long, which might wrap or truncate on narrow terminals, though the saturating_sub centering logic handles this gracefully.


119-128: LGTM! Error cleared on navigation.

Clearing the error message when the user changes difficulty selection is correct behavior, ensuring the error state doesn't persist inappropriately.


184-184: LGTM! Error state correctly passed to view.

The error message is properly passed to the view using as_ref(), enabling the conditional rendering of errors in the UI.

git_repository: Option<GitRepository>,
action_result: Option<TitleAction>,
needs_render: bool,
error_message: Option<String>,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clear error_message in the init() method.

The field is properly initialized in new(), but the init() method (line 89) doesn't clear error_message. If the screen is re-initialized after displaying an error (e.g., returning from another screen), the stale error message will persist until the user navigates.

Apply this diff to clear the error message in init():

 fn init(&mut self) -> Result<()> {
     self.action_result = None;
+    self.error_message = None;
     self.needs_render = true;

Also applies to: 53-53

🤖 Prompt for AI Agents
In src/presentation/game/screens/title_screen.rs around lines 36 and 53 (field
declaration) and update the init() method (around line 89) to clear any stale
error state: set the screen's error_message to None at the start of init() so
that re-initializing the screen removes any previously displayed error; ensure
you mutate the proper struct field (e.g., self.error_message = None) before
returning from init().

@unhappychoice unhappychoice merged commit 65895b6 into main Oct 5, 2025
5 of 7 checks passed
@unhappychoice unhappychoice deleted the feature/fix-empty-repo-panic branch October 5, 2025 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Panic when selecting difficulty with empty repository

1 participant