Skip to content

fix(admin): surface API error message in toasts#1653

Open
paanSinghCoder wants to merge 7 commits into
mainfrom
fix/admin-surface-server-error-toast
Open

fix(admin): surface API error message in toasts#1653
paanSinghCoder wants to merge 7 commits into
mainfrom
fix/admin-surface-server-error-toast

Conversation

@paanSinghCoder
Copy link
Copy Markdown
Contributor

@paanSinghCoder paanSinghCoder commented May 27, 2026

Summary

Admin toasts were either hiding the server's error reason behind a generic message, or showing it with the raw gRPC code prefix (e.g. [failed_precondition] ...). This PR makes admin error toasts surface the clean, human-readable server message in the toast description.

Two related changes:

  1. Surface the message where it was dropped — catch blocks that only showed a generic title now forward error instanceof ConnectError ? error.rawMessage : undefined into description.
  2. Strip the [code] prefix — toasts that already showed the server message via error.message (which connect-es formats as [code] message) now use error.rawMessage (the message without the prefix). rawMessage is always a string on a ConnectError, and every call is guarded, so behavior is unchanged for non-ConnectError errors.

Affected paths & the message users will now see

Newly surfaced (previously generic title only)

Path RPC Example message now shown
organizations/details/projects/members/remove-member.tsx removeProjectMember "principal is not a member of the resource"
organizations/details/projects/rename-project.tsx updateProject "already exist" / "not found"
preferences/details.tsx createPreferences "invalid value for preference"
webhooks/webhooks/create/index.tsx createWebhook "internal server error" *
webhooks/webhooks/update/index.tsx updateWebhook "internal server error" *
webhooks/webhooks/delete/index.tsx deleteWebhook "internal server error" *

Prefix removed ([code] msg → clean msg)

Path RPC Example message now shown
organizations/details/members/remove-member.tsx removeOrganizationMember "cannot change role: this is the last owner of the organization"
organizations/details/security/block-organization.tsx disable/enableOrganization "internal server error" *
organizations/details/security/domains-list.tsx deleteOrganizationDomain "domain whitelist request doesn't exist"
organizations/details/layout/add-tokens-dialog.tsx delegatedCheckout "internal server error" *
organizations/details/layout/invite-users-dialog.tsx createOrganizationInvitation "principal is already a member of the resource" / "Invalid email"
organizations/details/edit/billing.tsx updateBillingAccountDetails "cannot create predated invoices: due in days should be greater than 0"
organizations/details/edit/kyc.tsx setOrganizationKyc "link cannot be empty" / "org doesn't exist"
organizations/details/projects/use-add-project-members.tsx setProjectMemberRole "role is not valid for project scope"
users/list/invite-users.tsx createOrganizationInvitation "principal is already a member of the resource" / "Invalid email"
users/details/security/block-user.tsx disable/enableUser "user doesn't exist"
users/details/security/sessions/revoke-session-final-confirm.tsx revokeUserSession "invalid session_id format: must be a valid UUID"

* These backend handlers currently map all failures to a generic internal server error, so the description shows that until the backend returns more specific errors. This is no worse than the previous generic toast, and verified non-empty so the description never renders blank.

Test plan

  • Trigger a failing action on each path (e.g. remove the last org owner, rename a project to a duplicate name, invite an already-member user) and confirm the toast description shows the clean server message
  • Confirm no toast shows a [failed_precondition]-style [code] prefix anymore
  • Confirm non-ConnectError failures still render a toast with no description (unchanged)

🤖 Generated with Claude Code

Forward ConnectError.rawMessage into the toast description for the
remaining admin catch blocks that previously showed only a generic
error: project member removal, project rename, preference save, and
webhook create/update/delete. Falls back to no description for
non-ConnectError errors so behavior is unchanged for those.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview, Comment Jun 1, 2026 8:34am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved error messages throughout the admin panel across multiple features including organization billing, KYC verification, project management, security operations, webhook management, user administration, and preference settings. Error notifications now display more informative and detailed messaging when operations fail, providing better clarity about encountered issues and helping users understand what went wrong.

Walkthrough

This PR standardizes error toast descriptions across admin UI components by replacing error.message with error.rawMessage, and refactors several components to use a centralized handleConnectError utility for structured ConnectRPC error-code handling.

Changes

Error Toast rawMessage Standardization

Layer / File(s) Summary
Simple rawMessage property updates
web/sdk/admin/views/organizations/details/edit/billing.tsx, web/sdk/admin/views/organizations/details/edit/kyc.tsx, web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx, web/sdk/admin/views/organizations/details/security/block-organization.tsx, web/sdk/admin/views/organizations/details/security/domains-list.tsx, web/sdk/admin/views/users/details/security/block-user.tsx
Mutation error handlers update toast descriptions to read from error.rawMessage instead of error.message, without changing error handling structure.
handleConnectError handler description updates
web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx, web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx, web/sdk/admin/views/users/list/invite-users.tsx
Components already using handleConnectError update their InvalidArgument and Default error handler toast descriptions to use err.rawMessage instead of err.message.
New handleConnectError integration
web/sdk/admin/views/organizations/details/members/remove-member.tsx, web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx, web/sdk/admin/views/organizations/details/projects/rename-project.tsx, web/sdk/admin/views/preferences/details.tsx, web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx, web/sdk/admin/views/webhooks/webhooks/create/index.tsx, web/sdk/admin/views/webhooks/webhooks/delete/index.tsx, web/sdk/admin/views/webhooks/webhooks/update/index.tsx
Components import handleConnectError and refactor mutation error handlers to branch on specific error codes (PermissionDenied, AlreadyExists, NotFound, InvalidArgument) with targeted toast messages, while using err.rawMessage in default error descriptions. preferences/details.tsx also updates a test fixture data-test-id value.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • raystack/frontier#1499: Earlier PR introducing the handleConnectError utility pattern for centralized ConnectRPC error-to-toast mapping that this PR builds upon.
  • raystack/frontier#1550: Concurrent refactor of web/sdk/admin/views/organizations/details/members/remove-member.tsx that migrates the underlying mutation contract from removeOrganizationUser to removeOrganizationMember.

Suggested reviewers

  • rsbh
  • rohanchkrabrty
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coveralls
Copy link
Copy Markdown

coveralls commented May 27, 2026

Coverage Report for CI Build 26744068102

Coverage remained the same at 43.06%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 37887
Covered Lines: 16314
Line Coverage: 43.06%
Coverage Strength: 12.08 hits per line

💛 - Coveralls

…tions

Refactor error handling across various admin components to display the rawMessage from ConnectError in toast notifications instead of the generic error message. This change enhances the clarity of error reporting for users.
@paanSinghCoder paanSinghCoder marked this pull request as ready for review June 1, 2026 08:33
Copy link
Copy Markdown
Contributor

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
web/sdk/admin/views/organizations/details/edit/billing.tsx (1)

117-160: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid double error toasts in billing update

updateBillingDetails is awaited in onSubmit and the mutation has an onError handler, so failures trigger both:

  • onError shows error.rawMessage
  • the catch block shows the generic "Failed to update billing details"

Remove the toast from the catch (keep logging) to preserve the server error message.

♻️ Proposed change (drop redundant catch toast)
     } catch (error) {
-      toastManager.add({
-        title: "Something went wrong",
-        description: "Failed to update billing details",
-        type: "error",
-      });
       console.error("Failed to update billing details:", error);
     }
web/sdk/admin/views/preferences/details.tsx (1)

241-248: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

data-test-id passed to PreferenceValue is ignored.

PreferenceValueProps (lines 23-27) does not declare data-test-id, and PreferenceValue does not forward it to the rendered Input/Switch. The attribute on Line 247 is a no-op; the input still carries the hardcoded admin-preference-value-input from Line 47. If the test hook needs to change, update the inner element instead.

web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx (1)

24-43: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Fix async error handling in revoke-session-final-confirm
In web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx (handleConfirm), onConfirm is () => void and is called synchronously inside a try/catch without await, so this catch only handles synchronous throws—any ConnectError from an async revoke triggered by onConfirm won’t reach handleConnectError. Also, onOpenChange(false) closes the dialog immediately after onConfirm() is kicked off. Change onConfirm to return a Promise and await it before mapping errors/closing, or move async error handling to the caller where the revoke request is awaited.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: de7805df-2c12-4712-b731-5f336bf06105

📥 Commits

Reviewing files that changed from the base of the PR and between 0e8b178 and adf3093.

📒 Files selected for processing (17)
  • web/sdk/admin/views/organizations/details/edit/billing.tsx
  • web/sdk/admin/views/organizations/details/edit/kyc.tsx
  • web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx
  • web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx
  • web/sdk/admin/views/organizations/details/members/remove-member.tsx
  • web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx
  • web/sdk/admin/views/organizations/details/projects/rename-project.tsx
  • web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx
  • web/sdk/admin/views/organizations/details/security/block-organization.tsx
  • web/sdk/admin/views/organizations/details/security/domains-list.tsx
  • web/sdk/admin/views/preferences/details.tsx
  • web/sdk/admin/views/users/details/security/block-user.tsx
  • web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx
  • web/sdk/admin/views/users/list/invite-users.tsx
  • web/sdk/admin/views/webhooks/webhooks/create/index.tsx
  • web/sdk/admin/views/webhooks/webhooks/delete/index.tsx
  • web/sdk/admin/views/webhooks/webhooks/update/index.tsx

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.

2 participants