Skip to content

Scroll to history 080526#2361

Closed
simo6529 wants to merge 4 commits into
mainfrom
scroll-to-history-080526
Closed

Scroll to history 080526#2361
simo6529 wants to merge 4 commits into
mainfrom
scroll-to-history-080526

Conversation

@simo6529
Copy link
Copy Markdown
Collaborator

@simo6529 simo6529 commented May 8, 2026

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Enhanced error handling for serial jump navigation with loading overlay timeout protection
    • Added error toast notifications when targets cannot be found or resolved during navigation
    • Improved failure recovery to keep chat thread usable when jump operations stall
  • Documentation

    • Updated guidance on serial jump navigation edge cases, timeout behavior, and failure recovery

simo6529 added 3 commits May 8, 2026 11:39
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements structured failure handling for serial jump (scroll-to-target) operations in wave navigation. It introduces typed failure reasons, adds optional failure callbacks throughout the fetch and scroll pipeline, and wires error toast UI in the component layer.

Changes

Serial Jump Failure Handling

Layer / File(s) Summary
Failure Types & Contracts
contexts/wave/utils/wave-messages-utils.ts
New exported types: SerialJumpFailureReason (union of failure codes), SerialJumpFailure (reason + waveId + targetSerialNo + details), and OnSerialJumpFailure callback type. Internal DropIdsSerialLookupError class carries typed failure reason and metadata.
Utility Helpers
contexts/wave/utils/wave-messages-utils.ts
New internal helpers: isAbortError() to detect abort signals, getErrorDetails() to normalize unknown errors into structured Record<string, unknown>.
Light Fetch with Failure Reporting
contexts/wave/utils/wave-messages-utils.ts
fetchLightWaveMessages() now accepts optional onFailure callback. On error: re-throws abort errors, calls onFailure with typed reason and details for DropIdsSerialLookupError instances, maps other errors to reason: "fetch_failed".
Pagination Error Classification
contexts/wave/utils/wave-messages-utils.ts
findDropIdsBySerialNoWithPagination() refactored to throw DropIdsSerialLookupError with reason: "target_not_found", "fetch_failed", or "history_window_exhausted" depending on pagination outcome; includes rich metadata about requests and bounds.
Scroll Hook Failure Interface
components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts
Added onSerialScrollFailure?: (failure: SerialJumpFailure) => void to UseWaveDropsSerialScrollParams interface.
Scroll Hook Error Details Helper
components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts
New getErrorDetails() helper extracts structured error information from unknown exceptions.
Scroll Hook Failure Reporters
components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts
Added reportSerialScrollFailure() (guards duplicate reporting via hasReportedScrollFailureRef) and reportActiveScrollFailure() wrapper to invoke onSerialScrollFailure with enriched failure details.
Scroll Hook Lifecycle Wiring
components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts
Integrated failure reporting into: operation/DOM timeouts (via reportActiveScrollFailure), fetch invocations (forwarding onSerialScrollFailure callback), reveal failures, and catch blocks. Updated effect dependencies to include new reporters.
Pagination Type Extension
contexts/wave/hooks/useWavePagination.ts
Extended NextPageLightProps with optional onSerialScrollFailure?: OnSerialJumpFailure property.
Pagination Callback Flow
contexts/wave/hooks/useWavePagination.ts
fetchNextPage() conditionally passes onSerialScrollFailure to fetchLightWaveMessages() when available for light drops.
Component Failure Messaging
components/waves/drops/wave-drops-all/index.tsx
Defined constants mapping SerialJumpFailureReason to user-facing toast messages; added helper to select message by reason.
Component Auth & Callback
components/waves/drops/wave-drops-all/index.tsx
Updated useAuth() to extract setToast; created handleSerialScrollFailure() callback to emit toast on scroll failures.
Component Hook Integration
components/waves/drops/wave-drops-all/index.tsx
Passed handleSerialScrollFailure into useWaveDropsSerialScroll as onSerialScrollFailure to activate toast behavior.
Core Utility Tests
__tests__/contexts/wave/utils/wave-messages-utils.additional.test.ts
Updated fetchLightWaveMessages() test cases to: verify onFailure callback is not called on success, verify it is called with reason: "target_not_found" when target is missing, verify it is called with reason: "fetch_failed" on fetch errors.
Pagination Hook Tests
__tests__/contexts/wave/hooks/useWavePagination.test.ts
Added test for abort handling (ensuring console.error is not called), added test verifying onSerialScrollFailure callback is passed through to fetchLightWaveMessages(). Reformatted mocks and assertions to use consistent quotes and wrapping.
Component Tests
__tests__/components/waves/drops/WaveDropsAll.test.tsx
Added toast message constants; mocked setToast in auth setup; added helper for advancing timers within act blocks. Expanded "Serial Target Hydration Suspension" suite with tests verifying: fetch rejection with toast, fetch null return without toast, reveal failure with toast, target-missing callback without toast, target DOM timeout with toast, operation watchdog timeout with toast and overlay clearance.
Documentation
docs/waves/chat/feature-serial-jump-navigation.md
Documented edge cases: stalled jumps (timeout clears overlay, toast shown, thread remains usable), unresolved targets (short error toast, chat stays in place). Listed structured failure reason codes.

Sequence Diagram(s)

sequenceDiagram
  participant UI as WaveDropsAll
  participant Hook as useWaveDropsSerialScroll
  participant Pag as useWavePagination
  participant Fetch as fetchLightWaveMessages
  
  UI->>Hook: Call with onSerialScrollFailure
  Hook->>Pag: Initiate fetchNextPage
  Pag->>Fetch: Call with onSerialScrollFailure callback
  activate Fetch
  Fetch->>Fetch: Attempt drop-ids lookup
  alt Success
    Fetch-->>Pag: Return merged drops
  else Target Not Found
    Fetch->>Fetch: Throw DropIdsSerialLookupError
    Fetch->>Pag: Invoke onSerialScrollFailure
  else Fetch Failed
    Fetch->>Fetch: Throw DropIdsSerialLookupError
    Fetch->>Pag: Invoke onSerialScrollFailure
  end
  deactivate Fetch
  Pag->>Hook: Propagate callback result
  alt Timeout or error detected
    Hook->>Hook: reportActiveScrollFailure
  end
  Hook->>Hook: Check hasReportedScrollFailureRef
  Hook->>UI: Invoke onSerialScrollFailure with failure
  UI->>UI: Map reason to toast message
  UI->>UI: Display error toast
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • ragnep
  • prxt6529
  • GelatoGenesis

Poem

🐰 A rabbit hops through failure's maze,
With toast that pops and lights ablaze,
Each jump now typed, no mystery—
When targets hide, we toast with glee!
Watchdogs bark, yet streams flow free,
Error reasons dance in harmony. ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Scroll to history 080526' is vague and generic, using a date suffix without conveying meaningful information about the changeset's purpose or content. Consider a more descriptive title that explains the main change, such as 'Add serial jump failure handling and error reporting' or similar that reflects the core functionality.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch scroll-to-history-080526

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

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (2)
contexts/wave/hooks/useWavePagination.ts (1)

276-298: 💤 Low value

Consider simplifying the conditional fetch logic.

The current implementation has three separate branches. Since fetchLightWaveMessages accepts an optional onFailure parameter, you could simplify to two branches without the inner conditional:

♻️ Optional simplification
      let rawPromise: Promise<(ApiDrop | ApiDropId)[] | null>;
      if (props.type === DropSize.FULL) {
        rawPromise = fetchWaveMessages(
          props.waveId,
          oldestSerialNo,
          controller.signal
        );
-     } else if (props.onSerialScrollFailure) {
-       rawPromise = fetchLightWaveMessages(
-         props.waveId,
-         oldestSerialNo,
-         props.targetSerialNo,
-         controller.signal,
-         props.onSerialScrollFailure
-       );
      } else {
        rawPromise = fetchLightWaveMessages(
          props.waveId,
          oldestSerialNo,
          props.targetSerialNo,
-         controller.signal
+         controller.signal,
+         props.onSerialScrollFailure
        );
      }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contexts/wave/hooks/useWavePagination.ts` around lines 276 - 298, The
three-branch fetch can be collapsed into two: if props.type === DropSize.FULL
call fetchWaveMessages(...) into rawPromise; otherwise call
fetchLightWaveMessages(...) passing props.waveId, oldestSerialNo,
props.targetSerialNo, controller.signal and pass props.onSerialScrollFailure
(it’s optional) so you no longer need the inner conditional; update the
assignment to rawPromise accordingly and keep the same parameter order and
signals used in the existing calls to fetchLightWaveMessages and
fetchWaveMessages.
components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts (1)

86-97: 💤 Low value

Consider extracting shared getErrorDetails helper.

This function is duplicated from wave-messages-utils.ts. While the duplication is minor, extracting it to a shared utility would improve maintainability.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts`
around lines 86 - 97, The getErrorDetails function is duplicated; extract it
into a shared utility (e.g., export getErrorDetails from a new or existing
shared errors/util module) and replace the local implementation in
useWaveDropsSerialScroll.ts with an import from that shared module; also update
wave-messages-utils.ts to import and use the same exported getErrorDetails to
remove the duplicate definition and keep a single source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts`:
- Around line 86-97: The getErrorDetails function is duplicated; extract it into
a shared utility (e.g., export getErrorDetails from a new or existing shared
errors/util module) and replace the local implementation in
useWaveDropsSerialScroll.ts with an import from that shared module; also update
wave-messages-utils.ts to import and use the same exported getErrorDetails to
remove the duplicate definition and keep a single source of truth.

In `@contexts/wave/hooks/useWavePagination.ts`:
- Around line 276-298: The three-branch fetch can be collapsed into two: if
props.type === DropSize.FULL call fetchWaveMessages(...) into rawPromise;
otherwise call fetchLightWaveMessages(...) passing props.waveId, oldestSerialNo,
props.targetSerialNo, controller.signal and pass props.onSerialScrollFailure
(it’s optional) so you no longer need the inner conditional; update the
assignment to rawPromise accordingly and keep the same parameter order and
signals used in the existing calls to fetchLightWaveMessages and
fetchWaveMessages.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7f25681b-e5af-4fff-9c92-581f65d06eed

📥 Commits

Reviewing files that changed from the base of the PR and between 5dcdc91 and faa2acf.

📒 Files selected for processing (8)
  • __tests__/components/waves/drops/WaveDropsAll.test.tsx
  • __tests__/contexts/wave/hooks/useWavePagination.test.ts
  • __tests__/contexts/wave/utils/wave-messages-utils.additional.test.ts
  • components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts
  • components/waves/drops/wave-drops-all/index.tsx
  • contexts/wave/hooks/useWavePagination.ts
  • contexts/wave/utils/wave-messages-utils.ts
  • docs/waves/chat/feature-serial-jump-navigation.md

@sonarqubecloud
Copy link
Copy Markdown

@simo6529 simo6529 closed this May 11, 2026
@simo6529 simo6529 deleted the scroll-to-history-080526 branch May 11, 2026 06:37
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.

1 participant