Skip to content

fix(platform): improve member context error handling and agent autosave#580

Merged
larryro merged 2 commits into
mainfrom
fix/member-context-errors-and-agent-autosave
Feb 26, 2026
Merged

fix(platform): improve member context error handling and agent autosave#580
larryro merged 2 commits into
mainfrom
fix/member-context-errors-and-agent-autosave

Conversation

@larryro
Copy link
Copy Markdown
Collaborator

@larryro larryro commented Feb 26, 2026

Summary

  • Member context errors: getCurrentMemberContext now throws UnauthenticatedError instead of silently returning null, letting the frontend distinguish auth failures from missing membership. The dashboard layout handles query errors by showing a spinner instead of the access denied screen, and falls back gracefully when previous data exists.
  • Redundant prefetches removed: Route-level prefetches in $id.tsx and api-keys.tsx that duplicated the parent layout query have been removed. The settings index loader now catches query failures instead of crashing.
  • Agent form manual save: Custom agent general tab switches from debounced auto-save to manual save-on-blur, so team and shared-team changes persist immediately.
  • UDF timeout increase: Bumps the Convex UDF timeout from the default 1s to 5s in the Dockerfile to handle reconnect burst load (thundering herd).

Test plan

  • Added tests for skip=true when auth is loading and skip=false when auth is ready
  • Added test for spinner shown on query error (not access denied)
  • Added test for outlet remaining visible when query errors but previous data exists
  • Verify dashboard loads correctly for authenticated members
  • Verify access denied screen shows for non-members (no role)
  • Verify custom agent name/displayName/description save on blur
  • Verify team and shared team changes save immediately

🤖 Generated with Claude Code

… form to manual save

Throw UnauthenticatedError instead of returning null from getCurrentMemberContext
so the frontend can distinguish auth failures from missing membership. Handle
query errors gracefully in the dashboard layout by showing a spinner instead of
the access denied screen. Remove redundant route-level prefetches that duplicated
the parent layout query.

Switch custom agent general tab from auto-save to manual save-on-blur so team
and shared team changes persist immediately without debounce delays.

Increase Convex UDF timeout to 5s to handle reconnect burst load.
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Feb 26, 2026

Greptile Summary

This PR improves error handling and user experience across member context queries and agent form interactions.

Key improvements:

  • Better error handling: getCurrentMemberContext now throws UnauthenticatedError instead of silently returning null, allowing the frontend to distinguish between authentication failures and missing membership
  • Graceful fallback: Dashboard layout shows a spinner on query errors instead of access denied screen, and preserves the UI when cached data exists (clever use of ternary operator checking hasRole first)
  • Manual save control: Agent form switched from debounced auto-save to manual save-on-blur for text fields (name, displayName, description), with immediate save for team/shared-team changes - ensuring explicit user control
  • Performance optimization: UDF timeout increased from 2s to 5s to handle thundering herd on reconnect bursts
  • Cleanup: Removed redundant prefetches in child routes that duplicated parent layout queries

Test coverage: Comprehensive tests added for skip parameter behavior, error states, and graceful fallback scenarios.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk - all changes improve robustness and have comprehensive test coverage
  • Score reflects well-tested changes with clear improvements to error handling and UX. The error handling logic is sound (throwing UnauthenticatedError vs returning null for UnauthorizedError), the dashboard fallback logic cleverly uses ternary operator order to preserve UI when cached data exists, and manual save gives users explicit control. No breaking changes or risky operations.
  • No files require special attention

Important Files Changed

Filename Overview
services/platform/convex/members/queries.ts Changed to throw UnauthenticatedError instead of returning null for better error handling
services/platform/app/routes/dashboard/$id.tsx Removed prefetch loader, added isError handling, passes skip parameter to hook
services/platform/app/routes/dashboard/$id/custom-agents/$agentId/index.tsx Changed from auto-save to manual save-on-blur for text fields, immediate save for team changes
services/platform/app/routes/dashboard/tests/dashboard-layout.test.tsx Added comprehensive tests for skip parameter, error handling, and graceful fallback

Sequence Diagram

sequenceDiagram
    participant Frontend as Dashboard Layout
    participant Hook as useCurrentMemberContext
    participant Query as getCurrentMemberContext
    participant RLS as getOrganizationMember
    
    Note over Frontend,RLS: Authentication Flow
    Frontend->>Hook: useCurrentMemberContext(orgId, skip=isAuthLoading)
    alt Auth loading
        Hook-->>Frontend: {isLoading: true} (query skipped)
    else Auth ready
        Hook->>Query: Query member context
        alt No auth user
            Query-->>Hook: throw UnauthenticatedError
            Hook-->>Frontend: {isError: true, data: null}
            Frontend->>Frontend: Show spinner (no cached data)
        else User authenticated
            Query->>RLS: getOrganizationMember()
            alt Not a member
                RLS-->>Query: throw UnauthorizedError
                Query-->>Hook: return null
                Hook-->>Frontend: {data: null, isError: false}
                Frontend->>Frontend: Show access denied
            else Member found
                RLS-->>Query: return member
                Query-->>Hook: return member context
                Hook-->>Frontend: {data: {...}, isError: false}
                Frontend->>Frontend: hasRole ? Show outlet : Show spinner
            end
        end
        
        Note over Frontend: Error with cached data
        alt Query errors but cached data exists
            Hook-->>Frontend: {data: {...}, isError: true}
            Frontend->>Frontend: hasRole checks first → Show outlet (graceful fallback)
        end
    end
Loading

Last reviewed commit: f7eef28

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 26, 2026

📝 Walkthrough

Walkthrough

This PR coordinates multiple changes to improve authentication handling, query management, and form state management. Key changes include: (1) adding a skip parameter to the useCurrentMemberContext hook to conditionally disable queries during auth loading while preserving cache keys, (2) removing route-level prefetch loaders and moving data loading to components, (3) updating error handling in getCurrentMemberContext to throw UnauthenticatedError instead of returning null, (4) changing error propagation semantics to catch and return null instead of throwing, (5) introducing manual save mode to the custom agents form with per-field blur triggers, (6) updating comprehensive test coverage for skip behavior and error states, and (7) increasing the DATABASE_UDF_USER_TIMEOUT_SECONDS environment variable from 2 to 5 seconds.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Israeltheminer
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main changes: improved error handling in member context and refactored agent autosave mechanism, covering the two primary themes of this changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/member-context-errors-and-agent-autosave

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@services/platform/app/routes/dashboard/`$id/custom-agents/$agentId/index.tsx:
- Around line 157-163: When computing newShared for the save call, filter out
the newly selected primary team (resolved) so the primary team cannot appear in
sharedWithTeamIds; i.e., derive newShared from sharedWithTeamIds but remove
resolved when resolved is truthy (and only set state via setSharedWithTeamIds
when resolved is falsy per existing logic), then call save with
{...form.getValues(), teamId: resolved, sharedWithTeamIds: newShared} so the
payload never contains the primary team in sharedWithTeamIds; update references
to newShared, resolved, sharedWithTeamIds, setSharedWithTeamIds, save and
form.getValues() accordingly.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64f24ef and f7eef28.

📒 Files selected for processing (8)
  • services/platform/Dockerfile
  • services/platform/app/hooks/use-current-member-context.ts
  • services/platform/app/routes/dashboard/$id.tsx
  • services/platform/app/routes/dashboard/$id/custom-agents/$agentId/index.tsx
  • services/platform/app/routes/dashboard/$id/settings/api-keys.tsx
  • services/platform/app/routes/dashboard/$id/settings/index.tsx
  • services/platform/app/routes/dashboard/__tests__/dashboard-layout.test.tsx
  • services/platform/convex/members/queries.ts
💤 Files with no reviewable changes (1)
  • services/platform/app/routes/dashboard/$id/settings/api-keys.tsx

@larryro larryro merged commit 5ed7065 into main Feb 26, 2026
17 checks passed
@larryro larryro deleted the fix/member-context-errors-and-agent-autosave branch February 26, 2026 17:20
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.

1 participant