Skip to content

ADFA-3074: Clone error handling#1064

Open
dara-abijo-adfa wants to merge 2 commits intostagefrom
ADFA-3074-clone-error-handling
Open

ADFA-3074: Clone error handling#1064
dara-abijo-adfa wants to merge 2 commits intostagefrom
ADFA-3074-clone-error-handling

Conversation

@dara-abijo-adfa
Copy link
Contributor

  • Show Retry button when Git clone fails
  • Make error messages more descriptive

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 11, 2026

📝 Walkthrough

Release Notes - ADFA-3074: Clone Error Handling

Features

  • Retry button for failed clones: Users can now retry a failed Git clone operation without restarting the fragment
  • Improved error messaging: Connection errors are now categorized and displayed with specific, descriptive messages:
    • No internet connection
    • Connection lost
    • Unknown/generic errors
  • Network connectivity validation: Clone operations now check for network connectivity before attempting to clone

Changes

  • Clone fragment refactored: Clone logic extracted into a reusable helper function (cloneRepo()) to support both initial clone and retry actions
  • Enhanced error handling: Added detection for specific network exceptions (TransportException, UnknownHostException, EOFException) to provide targeted error messages
  • UI layout modernized:
    • Root layout converted from ConstraintLayout to ScrollView for better handling of form-heavy interface
    • Form structure reorganized with explicit margins and constraint definitions
    • Retry button added (hidden in idle/cloning states, shown on error)
  • String resource reorganization: Moved file status description strings from app module to resources module

Risks & Best Practice Considerations

  • ⚠️ Major layout restructuring: Significant changes to fragment_clone_repository.xml (149 lines added, 130 removed). Thorough testing of the UI layout on various screen sizes and orientations is recommended
  • ⚠️ String resource migration: File description strings were moved between modules. Verify that all references have been properly updated and no string resource mismatches exist
  • ⚠️ Retry UX: Ensure retry button behavior prevents rapid retry loops and provides appropriate user feedback to avoid confusion or abuse
  • ⚠️ Error mapping logic: Verify that all network error scenarios map correctly to the intended user-facing messages and that unknown errors fall back to a sensible default message

Walkthrough

The pull request enhances repository cloning functionality with network error detection and recovery. The ViewModel implements connectivity checks and maps network exceptions to specific error states. The Fragment refactors clone logic into a reusable helper and adds retry button support. The layout undergoes substantial restructuring to support scrolling, local path selection, and authentication fields. String resources are migrated and expanded.

Changes

Cohort / File(s) Summary
Clone Fragment Logic
app/src/main/java/com/itsaky/androidide/fragments/CloneRepositoryFragment.kt
Introduces cloneRepo() helper function to centralize input gathering and repository cloning. Adds retry button behavior—hidden during Idle/Cloning states, shown on Error state. Reuses helper for both initial and retry actions.
Clone ViewModel Error Handling
app/src/main/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModel.kt
Adds pre-clone network connectivity check. Enhances exception handling to distinguish network errors (TransportException, UnknownHostException, EOFException) and map them to specific error resources (no_internet_connection, connection_lost) or generic unknown error. Imports new exception types and NetworkUtils.
Clone Repository Layout
app/src/main/res/layout/fragment_clone_repository.xml
Replaces root ConstraintLayout with ScrollView container; adds MaterialTextView header. Introduces local path field with end icon, authentication checkbox, username/password fields with toggle behavior. Restructures action buttons to include exit, retry (initially hidden), and clone buttons. Reorganizes visibility flow with explicit constraints and margins.
String Resources
app/src/main/res/values/strings.xml, resources/src/main/res/values/strings.xml
Removed six file status descriptors from app module; added them and two connectivity error messages (no_internet_connection, connection_lost) to resources module, consolidating string management.

Sequence Diagram

sequenceDiagram
    actor User
    participant Fragment as CloneRepositoryFragment
    participant ViewModel as CloneRepositoryViewModel
    participant Network as NetworkUtils
    participant Git as Git Operations

    User->>Fragment: Click Clone Button
    Fragment->>Fragment: cloneRepo() - gather inputs
    Fragment->>ViewModel: cloneRepository(url, path, auth)
    
    ViewModel->>Network: checkConnectivity()
    alt No Internet
        Network-->>ViewModel: No Connection
        ViewModel-->>Fragment: Error(no_internet_connection)
        Fragment->>Fragment: Show Retry Button
    else Connected
        ViewModel->>Git: Perform Clone
        alt Success
            Git-->>ViewModel: Clone Complete
            ViewModel-->>Fragment: Success
        else Network Exception
            Git-->>ViewModel: TransportException/EOFException
            ViewModel->>ViewModel: Map to Error Resource
            ViewModel-->>Fragment: Error(connection_lost/unknown)
            Fragment->>Fragment: Show Retry Button
        end
    end
    
    User->>Fragment: Click Retry Button
    Fragment->>Fragment: cloneRepo() - reuse helper
    Fragment->>ViewModel: cloneRepository(same inputs)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • jatezzz
  • Daniel-ADFA
  • jomen-adfa
  • itsaky-adfa

Poem

🐰 A retry button hops with cheer,
Network errors now crystal clear,
Scrolling forms and auth so neat,
Clone and retry—the journey's sweet!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ADFA-3074: Clone error handling' directly relates to the main changes: enhanced error handling for clone operations and a retry button UI.
Description check ✅ Passed The description 'Show Retry button when Git clone fails; Make error messages more descriptive' accurately matches the changeset's core objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ADFA-3074-clone-error-handling

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.

Copy link
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/java/com/itsaky/androidide/fragments/CloneRepositoryFragment.kt (1)

165-182: ⚠️ Potential issue | 🟡 Minor

Missing retryButton visibility handling in Success state.

The retryButton visibility is set in Idle, Cloning, and Error states but not in Success. While the Success state quickly transitions away, explicitly hiding it ensures consistent UI state.

🛡️ Suggested fix
                            is CloneRepoUiState.Success -> {
                                cloneButton.isEnabled = true
+                               retryButton.visibility = View.GONE
                                statusText.text = getString(R.string.clone_successful)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/com/itsaky/androidide/fragments/CloneRepositoryFragment.kt`
around lines 165 - 182, In the CloneRepositoryFragment's handling of is
CloneRepoUiState.Success, explicitly hide the retryButton (e.g., set its
visibility to GONE or isVisible = false) before or when you reset the UI and
call viewModel.resetState so the button state stays consistent with
Idle/Cloning/Error branches; update the Success branch where cloneButton,
statusText, destDir check, and viewModel.resetState() are handled to include
hiding retryButton.
🧹 Nitpick comments (4)
resources/src/main/res/values/strings.xml (1)

1170-1177: Minor casing inconsistency in desc_file_conflicted.

The string "Conflicted File" uses title case, while all other desc_file_* strings use sentence case (e.g., "File added", "File modified"). Consider aligning the format for consistency.

💅 Suggested fix
-    <string name="desc_file_conflicted">Conflicted File</string>
+    <string name="desc_file_conflicted">File conflicted</string>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/src/main/res/values/strings.xml` around lines 1170 - 1177, The
string resource desc_file_conflicted is inconsistent (uses "Conflicted File"
title case) — update its value to match the other desc_file_* entries by using
the same sentence/phrase form; specifically change the value for string
name="desc_file_conflicted" to "File conflicted" so it aligns with "File added",
"File modified", etc.
app/src/main/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModel.kt (1)

163-165: String-based error detection is fragile but pragmatic.

The message matching for "Unexpected end of stream" and "Software caused connection abort" may differ across JGit versions and platforms. However, this is already preceded by an EOFException type check. If targeting more robustness, consider traversing the exception cause chain to check for SocketException or other IOException subtypes before falling back to message matching. Note that similar string-based matching patterns exist elsewhere in the codebase (e.g., WebServer.kt).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModel.kt`
around lines 163 - 165, Replace the fragile message-based detection in the
isConnectionDrop logic by walking the exception cause chain (starting from the
caught exception e) and checking for specific IO-related types like
EOFException, SocketException or other IOException subclasses before falling
back to string matching; update the check that currently uses e.cause and
e.message to iterate through causes and return true on any matching exception
type (refer to isConnectionDrop and the caught exception variable e) so the code
is robust across JGit versions/platforms while retaining the existing message
checks as a last resort.
app/src/main/res/layout/fragment_clone_repository.xml (2)

112-146: Minor: Inconsistent ID naming convention.

The button IDs mix naming styles:

  • exit_button (snake_case)
  • retryButton (camelCase)
  • cloneButton (camelCase)

While View Binding handles exit_button correctly (converts to exitButton), consistent naming improves maintainability. Consider standardizing on camelCase (exitButton) to match the others.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/res/layout/fragment_clone_repository.xml` around lines 112 -
146, Rename the inconsistent id exit_button to camelCase exitButton in the
layout and update all usages in code to match (replace R.id.exit_button or any
findViewById/reference and any viewBinding usages) so that ids for retryButton,
cloneButton, and exitButton use the same naming convention; after changing the
id, rebuild/run to fix any lingering references or generated binding names.

61-68: Consider using MaterialCheckBox for theme consistency.

The layout uses Material3 styles throughout (MaterialTextView, MaterialButton, Material TextInputLayout), but this CheckBox is the standard Android widget. Using com.google.android.material.checkbox.MaterialCheckBox would provide consistent theming and ripple behavior.

♻️ Suggested change
-        <CheckBox
+        <com.google.android.material.checkbox.MaterialCheckBox
             android:id="@+id/authCheckbox"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="16dp"
             android:text="@string/use_authentication"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toBottomOf="@id/localPathLayout" />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/res/layout/fragment_clone_repository.xml` around lines 61 - 68,
Replace the standard CheckBox in fragment_clone_repository.xml (id authCheckbox)
with the Material component to match the rest of your Material3 widgets: change
the XML tag to com.google.android.material.checkbox.MaterialCheckBox, keep the
existing attributes (android:id="@+id/authCheckbox", android:layout_width,
android:layout_height, android:layout_marginTop, android:text and constraint
attributes) and ensure your app uses the Material components theme and the
Material library dependency so the control inherits ripples and theming like
MaterialTextView/MaterialButton.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@app/src/main/java/com/itsaky/androidide/fragments/CloneRepositoryFragment.kt`:
- Around line 165-182: In the CloneRepositoryFragment's handling of is
CloneRepoUiState.Success, explicitly hide the retryButton (e.g., set its
visibility to GONE or isVisible = false) before or when you reset the UI and
call viewModel.resetState so the button state stays consistent with
Idle/Cloning/Error branches; update the Success branch where cloneButton,
statusText, destDir check, and viewModel.resetState() are handled to include
hiding retryButton.

---

Nitpick comments:
In
`@app/src/main/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModel.kt`:
- Around line 163-165: Replace the fragile message-based detection in the
isConnectionDrop logic by walking the exception cause chain (starting from the
caught exception e) and checking for specific IO-related types like
EOFException, SocketException or other IOException subclasses before falling
back to string matching; update the check that currently uses e.cause and
e.message to iterate through causes and return true on any matching exception
type (refer to isConnectionDrop and the caught exception variable e) so the code
is robust across JGit versions/platforms while retaining the existing message
checks as a last resort.

In `@app/src/main/res/layout/fragment_clone_repository.xml`:
- Around line 112-146: Rename the inconsistent id exit_button to camelCase
exitButton in the layout and update all usages in code to match (replace
R.id.exit_button or any findViewById/reference and any viewBinding usages) so
that ids for retryButton, cloneButton, and exitButton use the same naming
convention; after changing the id, rebuild/run to fix any lingering references
or generated binding names.
- Around line 61-68: Replace the standard CheckBox in
fragment_clone_repository.xml (id authCheckbox) with the Material component to
match the rest of your Material3 widgets: change the XML tag to
com.google.android.material.checkbox.MaterialCheckBox, keep the existing
attributes (android:id="@+id/authCheckbox", android:layout_width,
android:layout_height, android:layout_marginTop, android:text and constraint
attributes) and ensure your app uses the Material components theme and the
Material library dependency so the control inherits ripples and theming like
MaterialTextView/MaterialButton.

In `@resources/src/main/res/values/strings.xml`:
- Around line 1170-1177: The string resource desc_file_conflicted is
inconsistent (uses "Conflicted File" title case) — update its value to match the
other desc_file_* entries by using the same sentence/phrase form; specifically
change the value for string name="desc_file_conflicted" to "File conflicted" so
it aligns with "File added", "File modified", etc.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dcbb7850-fdea-4c82-8c29-611e9d07ba24

📥 Commits

Reviewing files that changed from the base of the PR and between 99c02e8 and 99aa492.

📒 Files selected for processing (5)
  • app/src/main/java/com/itsaky/androidide/fragments/CloneRepositoryFragment.kt
  • app/src/main/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModel.kt
  • app/src/main/res/layout/fragment_clone_repository.xml
  • app/src/main/res/values/strings.xml
  • resources/src/main/res/values/strings.xml
💤 Files with no reviewable changes (1)
  • app/src/main/res/values/strings.xml

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.

2 participants