Skip to content

fix: absorb fetch-level failures in apiFetch instead of throwing - #49

Merged
HahaSula merged 1 commit into
mainfrom
fix/chartapi-fetch-error-handling
Jul 6, 2026
Merged

fix: absorb fetch-level failures in apiFetch instead of throwing#49
HahaSula merged 1 commit into
mainfrom
fix/chartapi-fetch-error-handling

Conversation

@HahaSula

@HahaSula HahaSula commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Every wrapper in src/utils/chartApi.js only guards if (!res.ok). apiFetch called fetch() with no try/catch, so a transport-level failure (offline, DNS, aborted request) propagated as an unhandled rejection through every wrapper.
  • Worst at Promise.all call sites (SyncToModal, SyncFromModal), where a single rejected promise skips sibling .catches entirely and surfaces as an uncaught error in the modal.
  • Fixed centrally in apiFetch itself (per the issue's own suggested approach) rather than touching all ~25 wrappers individually — avoids two inconsistent error-handling styles in the same file. Each wrapper's existing if (!res.ok) return <fallback> now transparently absorbs transport failures too.

Test plan

  • npm test — 337/338 passing (1 pre-existing unrelated failure: git-lib.test.js locale mismatch on system git output, not touched by this change)
  • npm run lint — clean
  • Added unit test: apiFetch resolves to a failed response instead of throwing when fetch rejects
  • Added tests/unit/chartApi.test.js: listCharts, getSyncRegistry, createSync all return their documented fallback shape instead of throwing when the network request fails
  • Manually verified via a rejecting fetch mock that apiFetch no longer throws

Closes #45

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved app behavior when network requests fail, so failures now return a safe fallback response instead of crashing.
    • Chart-related actions now handle connectivity problems more gracefully, including empty results or clear failure responses.
  • Tests

    • Added coverage for request failures to confirm the app returns usable fallback data and does not throw on network errors.

apiFetch called fetch() with no try/catch, so a transport-level
failure (offline, DNS, aborted request) propagated as an unhandled
rejection through every chartApi.js wrapper, since they only guard
`if (!res.ok)`. Worst at Promise.all call sites (SyncToModal,
SyncFromModal) where one rejection skips sibling .catch entirely.

Fixed centrally in apiFetch itself so every existing wrapper's
`if (!res.ok) return <fallback>` transparently absorbs transport
failures too, without touching any of chartApi.js's ~25 wrappers.

Fixes #45
@rophy

rophy commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

PR Preview Bot

Preview environment failed to start.

...(truncated)
#20 DONE 1.8s

#21 [app] importing to docker
#21 loading layer cd1323d852fb 463.10kB / 463.10kB 0.2s done
#21 loading layer dd3465f3a89f 1.42kB / 1.42kB 0.1s done
#21 loading layer 1f5d4407c253 12.51kB / 12.51kB 0.1s done
#21 loading layer 3bec978af738 3.31kB / 3.31kB 0.1s done
#21 loading layer 37597d7ce11a 336B / 336B 0.1s done
#21 DONE 0.2s

#22 [app] resolving provenance for metadata file
#22 DONE 0.0s
 app  Built
 Network null-ptr-exception-rulemgmt-pr-49_default  Creating
 Network null-ptr-exception-rulemgmt-pr-49_default  Created
 Container null-ptr-exception-rulemgmt-pr-49-app-1  Creating
 Container null-ptr-exception-rulemgmt-pr-49-app-1  Created
 Container null-ptr-exception-rulemgmt-pr-49-app-1  Starting
Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint null-ptr-exception-rulemgmt-pr-49-app-1 (05fc9c980edd0ae37863462cf3f6bb5083e0357b691977f0b57a63511485b335): Bind for 127.0.0.1:12101 failed: port is already allocated

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

apiFetch is changed from a synchronous fetch wrapper into an async function that catches fetch rejections and returns a fallback response object (ok: false, status: 0, json() returning the error). New unit tests validate this fallback for apiFetch and chartApi's listCharts, getSyncRegistry, and createSync.

Changes

apiFetch Network Failure Handling

Layer / File(s) Summary
Fallback response on fetch rejection
src/lib/apiFetch.js, tests/unit/apiFetch.test.js, tests/unit/chartApi.test.js
apiFetch becomes async, wraps fetch in try/catch, and returns an ok: false fallback object with a json() method on rejection; new tests verify this behavior for apiFetch directly and for chartApi's listCharts, getSyncRegistry, and createSync fallback outputs.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant apiFetch
  participant fetch

  Caller->>apiFetch: apiFetch(path, opts)
  apiFetch->>fetch: fetch(url, opts)
  fetch-->>apiFetch: reject(Error)
  apiFetch-->>Caller: { ok: false, status: 0, json() }
Loading

Related issues: #45 (refactor: chartApi.js wrapper functions don't handle network-level fetch failures) — addressed by centralizing fetch failure handling in apiFetch.

Suggested labels: bug, tests

Suggested reviewers: null-ptr-exception

Poem:
A fetch that failed once left us stranded,
Now caught in a net, gently landed.
No throws, no crash, just ok: false,
A tidy fallback, a graceful pause.
Tests confirm it, hop hop, hooray! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: handling fetch-level failures in apiFetch instead of throwing.
Linked Issues check ✅ Passed Centralizing transport-failure handling in apiFetch and adding wrapper tests addresses #45's network-level fetch failures while preserving fallback shapes.
Out of Scope Changes check ✅ Passed The changes stay within the requested error-handling fix and related tests, with no clear unrelated scope added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 fix/chartapi-fetch-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.

@HahaSula

HahaSula commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/unit/chartApi.test.js (1)

1-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Good coverage for the three wrappers; consider extending to remaining chartApi.js exports.

Tests validate listCharts, getSyncRegistry, and createSync fallback correctly on network failure, matching the documented upstream contract. Since issue #45 calls out a fix across the entire chartApi.js file (including endpoints used by SyncToModal/SyncFromModal), consider adding similar fallback tests for any remaining wrappers not covered here to fully close out the issue.

🤖 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 `@tests/unit/chartApi.test.js` around lines 1 - 28, The current tests cover the
main fallback wrappers in chartApi.js, but the issue is broader and should be
validated across all exported request helpers. Add similar network-failure
fallback assertions for any remaining chartApi.js functions referenced by
SyncToModal and SyncFromModal, using the existing patterns in listCharts,
getSyncRegistry, and createSync so each wrapper resolves to its documented safe
default instead of throwing.
🤖 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 `@tests/unit/chartApi.test.js`:
- Around line 1-28: The current tests cover the main fallback wrappers in
chartApi.js, but the issue is broader and should be validated across all
exported request helpers. Add similar network-failure fallback assertions for
any remaining chartApi.js functions referenced by SyncToModal and SyncFromModal,
using the existing patterns in listCharts, getSyncRegistry, and createSync so
each wrapper resolves to its documented safe default instead of throwing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 58d73374-1041-42d0-954e-57ea872d272f

📥 Commits

Reviewing files that changed from the base of the PR and between b1e0367 and f751500.

📒 Files selected for processing (3)
  • src/lib/apiFetch.js
  • tests/unit/apiFetch.test.js
  • tests/unit/chartApi.test.js

@HahaSula
HahaSula requested a review from rophy July 6, 2026 03:16
@HahaSula

HahaSula commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@rophy CI + CodeRabbit review both pass, ready for your review whenever you have a chance. Closes #45.

@rophy rophy left a comment

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.

Good fix — centralizing transport-error handling in apiFetch lets all existing if (!res.ok) guards absorb network failures transparently. Clean and well-tested.

@HahaSula
HahaSula merged commit 99c2018 into main Jul 6, 2026
4 checks passed
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.

refactor: chartApi.js wrapper functions don't handle network-level fetch failures

2 participants