Skip to content

fix(web): handle expired session profile fetch (#1448)#1449

Merged
tyler-dane merged 8 commits intomainfrom
codex-bug-fix-401-1448
Feb 16, 2026
Merged

fix(web): handle expired session profile fetch (#1448)#1449
tyler-dane merged 8 commits intomainfrom
codex-bug-fix-401-1448

Conversation

@tyler-dane
Copy link
Contributor

Closes #1448

Copilot AI review requested due to automatic review settings February 15, 2026 03:53
@cursor
Copy link

cursor bot commented Feb 15, 2026

You have run out of free Bugbot PR reviews for this billing cycle. This will reset on March 3.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Copy link
Contributor

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

Fixes the “silent 401” UX by surfacing an immediate toast when the initial /user/profile fetch fails due to an expired/unauthorized session, aligning behavior with expected login prompting for previously-authenticated users.

Changes:

  • Show a react-toastify error toast when UserApi.getProfile() fails with 401/403.
  • Reuse shared toast options and add a stable toastId to avoid duplicate toasts.
  • Update UserProvider tests to assert the unauthorized toast behavior.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

File Description
packages/web/src/auth/context/UserProvider.tsx Adds unauthorized handling for profile fetch to display a session-expired toast.
packages/web/src/auth/context/UserProvider.test.tsx Updates tests to validate toast behavior on 401 profile fetch responses.

Copilot AI review requested due to automatic review settings February 16, 2026 01:26
Copy link
Contributor

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 21 out of 22 changed files in this pull request and generated 4 comments.

Comment on lines +49 to +51
expect(screen.getAllByTestId("n-icon").length).toBeGreaterThan(0);
expect(screen.getAllByTestId("d-icon").length).toBeGreaterThan(0);
expect(screen.getAllByTestId("w-icon").length).toBeGreaterThan(0);
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

AGENTS.md explicitly asks tests in packages/web to avoid using data- attributes/test IDs and prefer semantic queries and user-visible behavior. This new assertion relies on getAllByTestId("n-icon"/"d-icon"/"w-icon"), which makes the test more implementation-coupled. Consider asserting the shortcut keys via accessible text/roles within the shortcut overlay (e.g., locate the Global shortcuts section and assert it contains the expected key labels).

Copilot generated this review using guidance from repository custom instructions.
Comment on lines 25 to 29
useKeyUpEvent({
combination: ["2"],
combination: ["d"],
deps: [navigate],
handler: () => navigate(ROOT_ROUTES.DAY),
});
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The new global navigation shortcut for "d" conflicts with an existing Now view shortcut: useNowShortcuts already registers combination: ["d"] to focus the task description (packages/web/src/views/Now/shortcuts/useNowShortcuts.ts:48-52). Since useGlobalShortcuts is mounted in the app layout, pressing "d" on the Now page will trigger both handlers (navigation + focus), which is likely unintended. Consider choosing non-conflicting global keys (e.g., keep numeric keys, use a modifier like Shift, or change the Now-view description shortcut) or adding route/context gating so only one handler runs.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 16, 2026 02:11
@tyler-dane tyler-dane force-pushed the codex-bug-fix-401-1448 branch from 77bdb0e to 68e97db Compare February 16, 2026 02:11
Copy link
Contributor

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 9 out of 10 changed files in this pull request and generated 2 comments.

Comment on lines 238 to 243
expect(mockToastError).toHaveBeenCalledWith(
"Session expired. Please log in again to reconnect Google Calendar.",
expect.objectContaining({
toastId: "profile-session-expired",
}),
);
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The test verifies the toast message for unauthorized responses but doesn't cover the FORBIDDEN (403) status code path. Add a test case for status 403 to ensure both unauthorized conditions trigger the toast.

Copilot uses AI. Check for mistakes.
});

it("should handle session fetch errors gracefully", async () => {
it("shows a login toast when profile fetch returns unauthorized", async () => {
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The test doesn't verify that console.error is NOT called for unauthorized responses. Add an assertion to confirm the error logging path is skipped when isUnauthorized is true.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 16, 2026 03:28
Copy link
Contributor

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 18 out of 19 changed files in this pull request and generated 2 comments.

Comment on lines +239 to +246
expect(mockToastError).toHaveBeenCalled();
const latestToastCall = mockToastError.mock.calls.at(-1);
expect(latestToastCall?.[1]).toEqual(
expect.objectContaining({
toastId: "session-expired-api",
autoClose: false,
closeOnClick: false,
draggable: false,
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The test assertion is checking the wrong parameter. toast.error is called with two parameters: the content (React element) as the first parameter, and options object as the second parameter. The assertion should check both parameters separately like in compass.api.test.ts (lines 112-120), not just the first parameter.

Copilot uses AI. Check for mistakes.
@tyler-dane tyler-dane merged commit 69311c5 into main Feb 16, 2026
5 checks passed
@tyler-dane tyler-dane deleted the codex-bug-fix-401-1448 branch February 16, 2026 03:48
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.

401 unauthorised error not handled

2 participants