Skip to content

refactor(api): centralize error-to-message mapping - #620

Open
Marvelg256 wants to merge 5 commits into
Agentpay-Org:mainfrom
Marvelg256:refactor/api-01-error-mapping
Open

refactor(api): centralize error-to-message mapping#620
Marvelg256 wants to merge 5 commits into
Agentpay-Org:mainfrom
Marvelg256:refactor/api-01-error-mapping

Conversation

@Marvelg256

Copy link
Copy Markdown

Add mapApiError() helper in src/lib/mapApiError.ts that translates unknown error values (ApiError shapes, Error instances, non-Error rejections) to a consistent { message, requestId } structure. Replace scattered inline error-to-message logic across 15 call sites with this single tested helper.

Changes:

  • New: src/lib/mapApiError.ts — mapApiError(error, fallback?) helper
  • New: src/lib/tests/mapApiError.test.ts — 26 comprehensive tests
  • Updated: src/lib/usePolling.ts — replace errorMessage()
  • Updated: src/lib/useApi.ts — use mapApiError for rate-limited/generic
  • Updated: src/lib/useApiMutation.ts — use mapApiError for message extraction
  • Updated: src/app/usage/page.tsx — replace describeError() with mapApiError
  • Updated: 9 additional page-level catch blocks (webhooks, search, api-keys, admin, export, services, agents, events, service detail/edit)
  • Fixed: pre-existing bug in api-keys/page.tsx where 'error' was undefined

Test output:
src/lib/tests/mapApiError.test.ts — 26/26 passed Targeted call-site tests — 264/265 passed (1 pre-existing failure) Full suite — 92/95 suites pass (3 pre-existing failures)

Preserves all existing fallback messages verbatim:
"failed to load", "failed to mutate", "Search failed", "Export failed"

Closes #354

Summary

Related issue

Type of change

  • Bug fix
  • Feature
  • Documentation
  • Test-only change
  • Refactor or maintenance

Local checks

Paste the result or explain why a docs-only change did not require the command.

  • npm run lint
  • npm run typecheck
  • npm test
  • npm run build

Coverage and tests

  • Relevant tests were added or updated.
  • Coverage expectations for touched modules are met or explained.
  • Edge cases or failure states are covered.

Accessibility and UI review

  • Keyboard navigation is preserved.
  • Screen-reader names, labels, and error messages were considered.
  • Screenshots or recordings are included for visible UI changes.
  • Loading, empty, disabled, and error states are covered when applicable.

Security review

  • No secrets, tokens, private keys, .env files, or generated artifacts are committed.
  • API, wallet, auth, or payment trust boundaries are described when touched.
  • User-provided text is validated, escaped, or rendered safely where relevant.

Notes for reviewers

Add mapApiError() helper in src/lib/mapApiError.ts that translates
unknown error values (ApiError shapes, Error instances, non-Error
rejections) to a consistent { message, requestId } structure.
Replace scattered inline error-to-message logic across 15 call sites
with this single tested helper.

Changes:
- New: src/lib/mapApiError.ts — mapApiError(error, fallback?) helper
- New: src/lib/__tests__/mapApiError.test.ts — 26 comprehensive tests
- Updated: src/lib/usePolling.ts — replace errorMessage()
- Updated: src/lib/useApi.ts — use mapApiError for rate-limited/generic
- Updated: src/lib/useApiMutation.ts — use mapApiError for message extraction
- Updated: src/app/usage/page.tsx — replace describeError() with mapApiError
- Updated: 9 additional page-level catch blocks (webhooks, search,
  api-keys, admin, export, services, agents, events, service detail/edit)
- Fixed: pre-existing bug in api-keys/page.tsx where 'error' was undefined

Test output:
  src/lib/__tests__/mapApiError.test.ts — 26/26 passed
  Targeted call-site tests — 264/265 passed (1 pre-existing failure)
  Full suite — 92/95 suites pass (3 pre-existing failures)

Preserves all existing fallback messages verbatim:
  "failed to load", "failed to mutate", "Search failed", "Export failed"

Closes Agentpay-Org#354
The onboarding and reports layouts reference pageTitles.onboarding and
pageTitles.reports but those keys were never added to the object.
UsageRow, PresetKey, PRESET_RANGES, toISODate, buildDateRangeAnnouncement,
UsageDateRangeFilters, UsageQueryRows, and deriveUsageRows were all
referenced but never imported. Also adds the missing useMemo for queryRows.
The original code had a stray }, []); after applyPreset that was a
syntax error from a broken useCallback wrapper. Fixing the syntax
error revealed that the memoization contract required useCallback
to keep the onPresetChange prop stable across re-renders.
… update

The 'uses the page from searchParams' test was calling getByText
synchronously after waitFor for the API call. React batches the
setItems/setLoading state updates from the mock resolution, so the
DOM wasn't updated yet. Wrapping in waitFor gives React time to
flush.
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.

Centralize API error-to-message mapping in one helper

1 participant