From d0c3af41f94510cd154752e4cc303ca7664cff8f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 15:40:20 +0000 Subject: [PATCH 1/4] Initial plan From 6efc6e7973ea909b7eb79fa4e85ce52550d98e18 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 15:43:12 +0000 Subject: [PATCH 2/4] fix: surface errors from useAsyncCallback in examples/base Agent-Logs-Url: https://github.com/forwardsoftware/react-auth/sessions/848c6a14-640a-4fb5-8f04-f3f09fbbedf8 Co-authored-by: panz3r <1754457+panz3r@users.noreply.github.com> --- examples/base/src/Content.tsx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/base/src/Content.tsx b/examples/base/src/Content.tsx index 8046a07..4759a07 100644 --- a/examples/base/src/Content.tsx +++ b/examples/base/src/Content.tsx @@ -6,14 +6,14 @@ import { useAuthClient } from './auth'; export const Content: React.FC = () => { const authClient = useAuthClient(); - const [doLogin, isLoginLoading] = useAsyncCallback(() => authClient.login(), [ + const [doLogin, isLoginLoading, loginError] = useAsyncCallback(() => authClient.login(), [ authClient, ]); - const [doRefresh, isRefreshLoading] = useAsyncCallback( + const [doRefresh, isRefreshLoading, refreshError] = useAsyncCallback( () => authClient.refresh(), [authClient] ); - const [doLogout, isLogoutLoading] = useAsyncCallback( + const [doLogout, isLogoutLoading, logoutError] = useAsyncCallback( () => authClient.logout(), [authClient] ); @@ -49,6 +49,10 @@ export const Content: React.FC = () => { {isLoginLoading ?

Login in progress..

: null} {isRefreshLoading ?

Refresh in progress..

: null} + {loginError != null ?

Login error: {loginError instanceof Error ? loginError.message : 'An error occurred'}

: null} + {refreshError != null ?

Refresh error: {refreshError instanceof Error ? refreshError.message : 'An error occurred'}

: null} + {logoutError != null ?

Logout error: {logoutError instanceof Error ? logoutError.message : 'An error occurred'}

: null} +

Tokens:

{JSON.stringify(authClient.tokens, null, 2)}
@@ -58,16 +62,20 @@ export const Content: React.FC = () => { function useAsyncCallback Promise>( callback: T, deps: DependencyList -): [T, boolean] { +): [T, boolean, unknown] { const [isLoading, setLoading] = useState(false); + const [error, setError] = useState(null); const cb = useCallback(async (...argsx: never[]) => { setLoading(true); + setError(null); try { return await callback(...argsx); + } catch (err) { + setError(err); } finally { setLoading(false); } }, deps) as T; - return [cb, isLoading]; + return [cb, isLoading, error]; } From ab28bff1f77963635b701decad0d64ef6fbbb311 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 17:12:54 +0000 Subject: [PATCH 3/4] fix(examples): combine isLoading and error into single state in useAsyncCallback Agent-Logs-Url: https://github.com/forwardsoftware/react-auth/sessions/7c5e293b-c00b-42f6-bdca-56b3c09b79bf Co-authored-by: panz3r <1754457+panz3r@users.noreply.github.com> --- examples/base/src/Content.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/base/src/Content.tsx b/examples/base/src/Content.tsx index 4759a07..eaadeef 100644 --- a/examples/base/src/Content.tsx +++ b/examples/base/src/Content.tsx @@ -59,22 +59,25 @@ export const Content: React.FC = () => { ); }; +type AsyncCallbackState = { isLoading: boolean; error: unknown }; + function useAsyncCallback Promise>( callback: T, deps: DependencyList ): [T, boolean, unknown] { - const [isLoading, setLoading] = useState(false); - const [error, setError] = useState(null); + const [{ isLoading, error }, setState] = useState({ + isLoading: false, + error: null, + }); const cb = useCallback(async (...argsx: never[]) => { - setLoading(true); - setError(null); + setState({ isLoading: true, error: null }); try { return await callback(...argsx); } catch (err) { - setError(err); - } finally { - setLoading(false); + setState({ isLoading: false, error: err }); + return; } + setState({ isLoading: false, error: null }); }, deps) as T; return [cb, isLoading, error]; From f2d184d0ced5877b175c72e0f6d436b83db21a1c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 17:15:50 +0000 Subject: [PATCH 4/4] fix(examples): address review feedback - role=alert, Parameters typing, 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> --- examples/base/src/Content.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/base/src/Content.tsx b/examples/base/src/Content.tsx index eaadeef..2244ee8 100644 --- a/examples/base/src/Content.tsx +++ b/examples/base/src/Content.tsx @@ -49,9 +49,9 @@ export const Content: React.FC = () => { {isLoginLoading ?

Login in progress..

: null} {isRefreshLoading ?

Refresh in progress..

: null} - {loginError != null ?

Login error: {loginError instanceof Error ? loginError.message : 'An error occurred'}

: null} - {refreshError != null ?

Refresh error: {refreshError instanceof Error ? refreshError.message : 'An error occurred'}

: null} - {logoutError != null ?

Logout error: {logoutError instanceof Error ? logoutError.message : 'An error occurred'}

: null} + {loginError != null ?

Login error: {loginError instanceof Error ? loginError.message : 'An error occurred'}

: null} + {refreshError != null ?

Refresh error: {refreshError instanceof Error ? refreshError.message : 'An error occurred'}

: null} + {logoutError != null ?

Logout error: {logoutError instanceof Error ? logoutError.message : 'An error occurred'}

: null}

Tokens:

{JSON.stringify(authClient.tokens, null, 2)}
@@ -64,21 +64,21 @@ type AsyncCallbackState = { isLoading: boolean; error: unknown }; function useAsyncCallback Promise>( callback: T, deps: DependencyList -): [T, boolean, unknown] { +): [(...args: Parameters) => Promise, boolean, unknown] { const [{ isLoading, error }, setState] = useState({ isLoading: false, error: null, }); - const cb = useCallback(async (...argsx: never[]) => { + const cb = useCallback(async (...argsx: Parameters) => { setState({ isLoading: true, error: null }); try { - return await callback(...argsx); + const result = await callback(...argsx); + setState({ isLoading: false, error: null }); + return result; } catch (err) { setState({ isLoading: false, error: err }); - return; } - setState({ isLoading: false, error: null }); - }, deps) as T; + }, deps); return [cb, isLoading, error]; }