Skip to content

fix(examples): surface errors from useAsyncCallback in examples/base#261

Merged
panz3r merged 4 commits intomainfrom
copilot/fix-useasynccallback-rejections
Apr 4, 2026
Merged

fix(examples): surface errors from useAsyncCallback in examples/base#261
panz3r merged 4 commits intomainfrom
copilot/fix-useasynccallback-rejections

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 4, 2026

Affected Package(s)

  • Examples

Related Issue(s)

Motivation

useAsyncCallback in examples/base had no error handling: a rejected callback left the UI permanently stuck in a loading state with no feedback and the error silently swallowed.

Description of Changes

  • useAsyncCallback hook: Added catch (err) block to capture errors from async callbacks. Replaced two separate useState calls (isLoading and error) with a single AsyncCallbackState object ({ isLoading: boolean; error: unknown }), so that starting a new invocation atomically sets isLoading: true and resets error: null in a single render pass. Return type changed from [T, boolean] to [(...args: Parameters<T>) => Promise<unknown>, boolean, unknown], removing the unsafe as T cast and using Parameters<T> to preserve argument types without a type assertion. Control flow restructured so the success path explicitly calls setState before returning the result, and the catch path calls setState and falls off naturally — eliminating previously unreachable code.
  • Content component: Destructures the third element (loginError, refreshError, logoutError) and renders them conditionally with safe message extraction and role="alert" for screen reader accessibility:
{loginError != null
  ? <p role="alert">Login error: {loginError instanceof Error ? loginError.message : 'An error occurred'}</p>
  : null}

Breaking Changes

None

How to Test

  1. CI Checks: Verify that all automated tests (Vitest) and build steps pass successfully on this PR.
  2. Local Verification (Optional):
    • cd examples/base && npm install && npm run dev
    • Wire up an AuthClient whose onLogin rejects — confirm the error message renders and the button is re-enabled immediately.

Checklist

  • My code follows the project's style guidelines
  • I have added or updated tests to cover the changes
  • I have updated relevant documentation
  • All tests are passing locally
  • CI checks are passing
  • I have reviewed my own code and lock file changes
  • I have checked for any potential security implications
  • I have verified the changes work as expected
  • My commit messages follow Conventional Commits format

Notes for Reviewers

No tests added — examples/ has no test infrastructure and is documentation/demo only. The fix is a self-contained change to a single file with no impact on published packages.

Copilot AI changed the title [WIP] Fix useAsyncCallback in examples/base to handle rejections fix: surface errors from useAsyncCallback in examples/base Apr 4, 2026
Copilot AI requested a review from panz3r April 4, 2026 15:43
@panz3r panz3r requested a review from Copilot April 4, 2026 17:06
@panz3r panz3r added bug Something isn't working examples Changes to example projects/packages labels Apr 4, 2026
@panz3r panz3r changed the title fix: surface errors from useAsyncCallback in examples/base fix(examples): surface errors from useAsyncCallback in examples/base Apr 4, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the examples/base demo UX by surfacing async action failures (login/refresh/logout) instead of leaving errors silent, and by exposing that error state from the local useAsyncCallback hook.

Changes:

  • Extend the local useAsyncCallback hook to track/reset an error state and return it as a third tuple element.
  • Update the Content component to destructure and conditionally render loginError, refreshError, and logoutError.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@panz3r
Copy link
Copy Markdown
Member

panz3r commented Apr 4, 2026

@copilot please have a look at the review comments and apply fixes that looks most appropriate/correct

…ping, fix unreachable setState

Agent-Logs-Url: https://github.com/forwardsoftware/react-auth/sessions/7e291b86-a295-4acd-967f-d5249adc4d40

Co-authored-by: panz3r <1754457+panz3r@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 4, 2026

@copilot please have a look at the review comments and apply fixes that looks most appropriate/correct

Done in f2d184d. Applied all three remaining review fixes:

  1. role="alert" added to all three error <p> elements for screen reader accessibility.
  2. Type safety: replaced useCallback(...) as T with (...argsx: Parameters<T>) and an explicit return type of [(...args: Parameters<T>) => Promise<unknown>, boolean, unknown] — no more unsafe cast.
  3. Unreachable setState: the old structure had setState({ isLoading: false, error: null }) after a try/catch where both branches returned, making it dead code. Restructured so success explicitly calls setState then returns the result, and the catch sets state and falls off naturally.

@panz3r panz3r marked this pull request as ready for review April 4, 2026 17:19
Copilot AI review requested due to automatic review settings April 4, 2026 17:19
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@panz3r panz3r merged commit d011a97 into main Apr 4, 2026
20 checks passed
@panz3r panz3r deleted the copilot/fix-useasynccallback-rejections branch April 4, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working examples Changes to example projects/packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: useAsyncCallback in examples/base swallows rejections silently

3 participants